SP3693题解报告

题目传送门

应该都是中国人吧,这个题目描述讲的比较通俗易懂。

首先,我们发现在 \([l, r]\) 中当 \((A_i + A_j)_{\max}\) 时,\(A_i\)\(A_j\)\([l, r]\) 中的最大值和非严格次大值。所以题目变成了单点赋值和查区间最大值和次大值。

我们发现,最大值和次大值这种东西是不具有可差分的性质的,因此不能使用树状数组,我们只能请出家里有矿的人在 WC 吃的东西线段树!,所以我们可以维护一个节点的最大值和次大值。由于此题是单点修改,所以不用懒惰标记,这也大大减少了实现难度!

思路不难,难点就是实现。

首先是 pushup,最大值很好处理,就是左右子树的最大值。对于次大值,它一定是左右子树中的最大值、次大值的一个。然而次大值的值可以说是跟在最大值屁股后面的,所以说次大值是左右子树中的最大值、次大值这 \(4\) 个值中最大的且小于等于最大值的数,就是这四个数的次大值。

如何求四个数的次大值呢?
最简单粗暴的方法是开一个数组,把它们四个存进去排序,输出第三个值。

所以求次大值的代码如下:

int sec(int a, int b, int c, int d){
  int tmp[] = {a, b, c, d};
  sort(tmp, tmp + 4);
  return tmp[2];
}

那么 pushup 也出来了(mx 为最大值,mx2 为次大值):

void pushup(int u){
  a[u].mx = max(a[ls(u)].mx, a[rs(u)].mx);
  a[u].mx2 = sec(a[ls(u)].mx, a[rs(u)].mx, a[ls(u)].mx2, a[rs(u)].mx2);
}

接下来就是建树了。跟普通线段树没有什么区别,只需要注意,当 l == r 时,最大值是 a[l],没有次大值,所以设为 -infinf 是一个大数,代码就不给了。

然后就是单点修改。也没什么好说的,就是递归到 l == r 的时候直接更新最大值为要修改的值即可,代码不给了。

最后就是查询。我们可以用两个 ans1ans2 表示最大值和次大值。由于线段树的递归是先左后右,所以当递归到需求的区间的子区间时,在它前面的子区间已经全部遍历过了。最大值的更新就不说了,同上面的分析,ans2前面区间的最大值,前面区间的次大值,当前子区间的最大值和次大值四个数中的次大值,用上面的 sec 函数即可。那么此题就做完了。

随后附上参考代码(删去了一些部分,直接复制会亖哦):

#include<bits/stdc++.h>
#define int long long
#define inf 1e17

using namespace std;

const int N = 1e5 + 5;

struct tree{
  int mx, mx2;
}a[4 * N];

int n, q, b[N], x, y, ans1, ans2;
char op;

int ls(int u){return u << 1;}
int rs(int u){return u << 1 | 1;}

int sec(int a, int b, int c, int d){
  int tmp[] = {a, b, c, d};
  sort(tmp, tmp + 4);
  return tmp[2];
}

void pushup(int u){
  a[u].mx = max(a[ls(u)].mx, a[rs(u)].mx);
  a[u].mx2 = sec(a[ls(u)].mx, a[rs(u)].mx, a[ls(u)].mx2, a[rs(u)].mx2);
}

void build(int u, int l, int r){
  if(l == r){
    a[u].mx = b[l];
    a[u].mx2 = -inf;
    return ;
  }
  // 省略
  pushup(u);
}

void update(int u, int l, int r, int x, int y){
  if(l == r){
    a[u].mx = y;
    return ;
  }
  //省略
  pushup(u);
}

void query(int u, int l, int r, int L, int R){
  if(L <= l && r <= R){
    ans2 = sec(a[u].mx2, a[u].mx, ans1, ans2);
    //省略ans1的更新
    return ;
  }
  //省略基本操作
}
//省略 mian 函数
posted @ 2026-02-02 21:37  tangtianyao0123  阅读(1)  评论(0)    收藏  举报