孩子调了一晚上了还是 WA 70pts
有且仅有 #21 WA on line 5433
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
class seg{
public:
struct Segmenttree{
int l,r;
int dat;
}t[2000007];
void pushup(int p){
// t[p].dat=t[p<<1].dat+t[p<<1|1].dat;
t[p].dat=max(t[p<<1].dat,t[p<<1|1].dat);
}
void build(int p,int l,int r,int b[]){
t[p].l=l;t[p].r=r;
if(l==r){
t[p].dat=b[l];
return;
}
int mid=(t[p].l+t[p].r)>>1;
build(p<<1,l,mid,b);
build(p<<1|1,mid+1,r,b);
pushup(p);
}
void modify(int p,int x,int dat){
if(t[p].l==t[p].r){
t[p].dat=dat;
return;
}
int mid=(t[p].l+t[p].r)>>1;
if(x<=mid)modify(p<<1,x,dat);
else if(x>mid)modify(p<<1|1,x,dat);
else puts("fuck");
pushup(p);
}
int query(int p,int l,int r){
if(l>r){
return 0;
}
if(l<=t[p].l&&t[p].r<=r){
return t[p].dat;
}
int mid=(t[p].l+t[p].r)>>1;
int res=0;
if(l<=mid)res=max(res,query(p<<1,l,r));
if(r>mid)res=max(res,query(p<<1|1,l,r));
pushup(p);
return res;
}
}t;
int n,m,w,a[500007],b[500007],num;
set<int>s[500007];
void update(int num,int val)//已有a[num]==pos,现进行线段树的更新
{
//仅有num的补前驱的补后驱仍是num(等价于num的补前驱在num等前驱后面)时b[num]!=0
//如果num的补前驱在num等前驱前面,则,没num什么事了
auto equal_front_of_val=s[val].find(num);
auto plus_front_of_val=s[w-val].upper_bound(num-1);
if(plus_front_of_val!=s[w-val].begin())//如果补前驱存在
{
if(equal_front_of_val==s[val].begin()){//等前驱不存在
--plus_front_of_val;
b[num]=*plus_front_of_val;
t.modify(1,num,b[num]);
}
else //两者都存在
if((*(--equal_front_of_val))<=(*(--plus_front_of_val)))//判断 num的补前驱在num等前驱后面 是否成立
{
b[num]=*plus_front_of_val;
t.modify(1,num,b[num]);
}
else{
b[num]=0;
t.modify(1,num,0);
}
}
else{
b[num]=0;
t.modify(1,num,0);
}
}
int main(){
cin>>n>>m>>w;
for(int i=1;i<=n;i++){
cin>>a[i];
if(s[w-a[i]].size())
if(s[a[i]].empty()||(*(--s[a[i]].end()))<=(*(--s[w-a[i]].end())))
b[i]=*(--s[w-a[i]].end());
s[a[i]].insert(i);
// cout<<b[i]<<' ';
}
t.build(1,1,n,b);
while(m--){
int op;
cin>>op;
if(op==1){
int pos,val;
cin>>pos>>val;
auto equal_back=s[a[pos]].upper_bound(pos);
auto plus_back=s[w-a[pos]].upper_bound(pos);
s[a[pos]].erase(pos);
s[val].insert(pos);//进行修改操作
if(equal_back!=s[a[pos]].end()){
update(*equal_back,a[pos]);//使得equal_back等于a[pos],更新其状态
}
if(plus_back!=s[a[pos]].end()){
update(*plus_back,w-a[pos]);//使得plus_back等于w-a[pos]
}
a[pos]=val;
equal_back=s[a[pos]].upper_bound(pos);
plus_back=s[w-a[pos]].upper_bound(pos);
if(equal_back!=s[a[pos]].end()){
update(*equal_back,a[pos]);
}
if(plus_back!=s[a[pos]].end()){
update(*plus_back,w-a[pos]);
}//与前面一模一样
update(pos,a[pos]);
}
else if(op==2){
int l,r;
cin>>l>>r;
l^=num;r^=num;
int q=t.query(1,l,r);
if(q>=l){
puts("Yes");
++num;
}
else puts("No");
}
else puts("fuckccf");
}
return 0;
}