d1t1
sol1:用线段树维护区间是否全0/全1,叶子上压位维护对应位置的数位,加法首先对叶子加,如需进位则向右找到第一个不是全1的叶子+1,中间部分全1部分打上反转标记,减法同理。
#include<cstdio> int _(){ int x=0,f=1,c=getchar(); while(c<48)c=='-'?f=-1:0,c=getchar(); while(c>47)x=x*10+c-48,c=getchar(); return x*f; } const int N=1100127; typedef unsigned int u32; int n,_l,flag; u32 _ans; int mx; struct node{ node*lc,*rc; int rev; u32 _or,_and; void revs(){ rev^=1; _or=~_or; _and=~_and; } void up(){ _or=lc->_or|rc->_or; _and=lc->_and&rc->_and; } void dn(){ if(rev){ rev^=1; lc->revs(); rc->revs(); } } void find(int L,int R){ if(L==R){ _ans=_or; return; } int M=(L+R)>>1; dn(); if(_l<=M)lc->find(L,M); else rc->find(M+1,R); } void inc(int L,int R){ if(L==R){ flag=(_and+_ans<_and); _and+=_ans; _or=_and; return; } int M=(L+R)>>1; dn(); if(_l<=M)lc->inc(L,M); else rc->inc(M+1,R); up(); } void dec(int L,int R){ if(L==R){ flag=(_and-_ans>_and); _and-=_ans; _or=_and; return; } int M=(L+R)>>1; dn(); if(_l<=M)lc->dec(L,M); else rc->dec(M+1,R); up(); } void inc1(int L,int R){ if(flag)return; if(_l<=L){ if(_and==~0u)return revs(); if(L==R){ _or=++_and; flag=1; return; } } dn(); int M=(L+R)>>1; if(_l<=M)lc->inc1(L,M); rc->inc1(M+1,R); up(); } void dec1(int L,int R){ if(flag)return; if(_l<=L){ if(_or==0u)return revs(); if(L==R){ _or=--_and; flag=1; return; } } dn(); int M=(L+R)>>1; if(_l<=M)lc->dec1(L,M); rc->dec1(M+1,R); up(); } }ns[N*2],*np=ns,*rt; node*build(int L,int R){ node*w=np++; if(L<R){ int M=(L+R)>>1; w->lc=build(L,M); w->rc=build(M+1,R); } w->_or=w->_and=w->rev=0; return w; } void inc(u32 a,int x){ if(!a)return; _ans=a;_l=x; rt->inc(0,mx); if(flag){ flag=0; _l=x+1; rt->inc1(0,mx); } } void dec(u32 a,int x){ if(!a)return; _ans=a;_l=x; rt->dec(0,mx); if(flag){ flag=0; _l=x+1; rt->dec1(0,mx); } } int main(){ n=_();_();_();_(); mx=n+10; if(mx<1000)mx=1000; rt=build(0,mx); for(int i=0;i<n;++i){ if(_()==1){ int a0=_(),b=_(); int b1=b>>5,b2=b&31; if(a0>0){ u32 a=a0; inc(a<<b2,b1); if(b2)inc(a>>(32-b2),b1+1); }else if(a0<0){ u32 a=-a0; dec(a<<b2,b1); if(b2)dec(a>>(32-b2),b1+1); } }else{ int k=_(); _l=k>>5; rt->find(0,mx); printf("%d\n",_ans>>(k&31)&1); } } return 0; }