*题解:P6617 查找 Search
解析
考虑对于每个位置 \(i\) 维护最大的位置 \(pre_i < i\) 满足 \(a_i+a_{pre_i}=w\),这样区间 \([l,r]\) 内存在编号和为 \(w\) 的充要条件就为 \(\max_{i=l}^rpre_i \ge l\),可以使用线段树来维护。
问题变为如何更新 \(pre\)。直接做的话单次修改会影响 \(O(n)\) 个位置,但是我们发现,如果对于 \(i<j,a_i = a_j\) 不存在 \(k\) 使得 \(a_k=w-a_i=w-a_j\),此时有 \(pre_i=pre_j\),那么我们不关心 \(pre_j\),因为如果询问区间包含 \(i,j\),那么只知道 \(pre_i\) 不影响结果,如果询问区间只包含 \(j\),那么在 \(j\) 之前也没有区间内的位置能够匹配。于是可以对于这样的 \(j\),直接将 \(pre_j\) 设为 \(0\)。这样做的好处就是形成了一个链式结构,元素的增删只会影响相邻元素。
具体地,我们可以这样实现,开 \(w\) 个 set 存储元素位置,值为 \(x\) 的元素的位置存在第 \(\min(x,w-x)\) 个 set 中,这样 set 中混合着 \(x\) 与 \(w-x\) 的位置。对于位置 \(i\) 的修改,更新修改前 \(i\) 所在集合的后继的 \(pre\),修改后 \(i\) 所在集合的后继的 \(pre\),以及修改后的 \(pre_i\)。修改后继时需要分类讨论后继对应的值是 \(a_i\) 还是 \(a_i - w\)。
时间复杂度 \(O(m \log n)\)。
代码
#include <bits/stdc++.h>
#define ls(p) ((p) << 1)
#define rs(p) (((p) << 1) | 1)
#define mid ((l + r) >> 1)
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N = 5e5 + 5,M = 500 * 500,mod = 998244353;
set<int> pos[N];
int pre[N],mx[N << 2],a[N];
void push_up(int p){
mx[p] = max(mx[ls(p)],mx[rs(p)]);
}
void modi(int p,int l,int r,int x){
if(l > x || r < x) return;
if(l == r){
mx[p] = pre[l];
return;
}
modi(ls(p),l,mid,x),modi(rs(p),mid + 1,r,x);
push_up(p);
}
int query(int p,int l,int r,int L,int R){
if(l > R || r < L) return -1;
if(l >= L && r <= R){
return mx[p];
}
return max(query(ls(p),l,mid,L,R),query(rs(p),mid + 1,r,L,R));
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
int n,m,w;
cin>>n>>m>>w;
for(int i=1;i<=n;i++){
cin>>a[i];
int k = min(a[i],w - a[i]);
if(!pos[k].empty() && a[*prev(pos[k].end())] == w - a[i]){
pre[i] = *prev(pos[k].end());
}
modi(1,1,n,i);
pos[k].insert(i);
}
int cnt = 0;
while(m--){
int op,x,y;
cin>>op>>x>>y;
if(op == 1){
int k = min(a[x],w - a[x]);
auto it = pos[k].find(x);
if(next(it) != pos[k].end()){
auto nxt = next(it);
if(a[*nxt] == w - a[x]){
if(it == pos[k].begin()){
pre[*nxt] = 0;
}else{
auto p = prev(it);
pre[*nxt] = a[*p] == w - a[x] ? 0 : *p;
}
}else{
pre[*nxt] = pre[x];
}
modi(1,1,n,*nxt);
}
pos[k].erase(it);
a[x] = y;
k = min(a[x],w - a[x]);
it = pos[k].lower_bound(x);
if(it == pos[k].begin()){
pre[x] = 0;
}else{
auto p = prev(it);
pre[x] = a[*p] == w - a[x] ? *p : 0;
}
if(it != pos[k].end()){
if(a[*it] == w - a[x]){
pre[*it] = x;
}else{
pre[*it] = 0;
}
modi(1,1,n,*it);
}
pos[k].insert(x);
modi(1,1,n,x);
}else{
x ^= cnt,y ^= cnt;
bool f = query(1,1,n,x,y) >= x;
cnt += f;
cout<<(f ? "Yes" : "No")<<'\n';
}
}
return 0;
}

浙公网安备 33010602011771号