题面
https://www.luogu.org/problem/P5055
题解
#include<cstdio> #include<iostream> #include<ctime> #include<cstdlib> using namespace std; const long long size=250000*50; struct fhq_treap { long long v[size],ch[size][2],fix[size],siz[size],sum[size]; bool rev[size]; long long root[200050]; long long cnt; void clear() {cnt=0; v[0]=ch[0][1]=ch[0][0]=fix[0]=siz[0]=sum[0]=rev[0]=0; root[0]=0;} void pushr(long long x) { if (!rev[x]) return; rev[x]=false; swap(ch[x][0],ch[x][1]); if (ch[x][0]) { copy(ch[x][0],++cnt); ch[x][0]=cnt; rev[cnt]^=1; } if (ch[x][1]) { copy(ch[x][1],++cnt); ch[x][1]=cnt; rev[cnt]^=1; } } void update(long long x) { siz[x]=1+siz[ch[x][0]]+siz[ch[x][1]]; sum[x]=v[x]+sum[ch[x][0]]+sum[ch[x][1]]; } void copy(long long x,long long y) { siz[y]=siz[x]; ch[y][0]=ch[x][0]; ch[y][1]=ch[x][1]; fix[y]=fix[x]; v[y]=v[x]; rev[y]=rev[x]; sum[y]=sum[x]; } // 1-k k+1-n void split(long long k,long long x,long long y,long long &ch1,long long &ch2) { if (x==0) { ch1=ch2=0; return; } copy(x,y); pushr(y); if (siz[ch[y][0]]+1<=k) { ch1=y; split(k-siz[ch[y][0]]-1,ch[y][1],++cnt,ch[y][1],ch2); //update(ch1); } else { ch2=y; split(k,ch[y][0],++cnt,ch1,ch[y][0]); //update(ch2); } update(y); } long long merge(long long x,long long y) { if (!x || !y) return x+y; pushr(x); pushr(y); if (fix[x]<fix[y]) { ch[x][1]=merge(ch[x][1],y); update(x); return x; } else { ch[y][0]=merge(x,ch[y][0]); update(y); return y; } } long long newnode(long long val) { ++cnt; sum[cnt]=v[cnt]=val; siz[cnt]=1; fix[cnt]=rand(); ch[cnt][0]=ch[cnt][1]=0; rev[cnt]=0; return cnt; } void insert(long long his,long long cur,long long p,long long val) { long long root1=0,root2=0; split(p,root[his],++cnt,root1,root2); root[cur]=merge(merge(root1,newnode(val)),root2); } void erase(long long his,long long cur,long long p) { long long root1=0,root2=0,root3=0; split(p-1,root[his],++cnt,root1,root3); split(1,root3,++cnt,root2,root3); root[cur]=merge(root1,root3); } long long query(long long his,long long cur,long long l,long long r) { long long root1=0,root2=0,root3=0; split(r,root[his],++cnt,root2,root3); split(l-1,root2,++cnt,root1,root2); //cout<<root2<<endl; long long ret=sum[root2]; root[cur]=merge(merge(root1,root2),root3); return ret; } void rever(long long his,long long cur,long long l,long long r) { long long root1=0,root2=0,root3=0; //split(l-1,root[his],++cnt,root1,root2); //split(r-l+1,root2,++cnt,root2,root3); split(r,root[his],++cnt,root2,root3); split(l-1,root2,++cnt,root1,root2); rev[root2]^=1; root[cur]=merge(merge(root1,root2),root3); } } treap; long long n; int main() { long long i,opt,his,p,x,lastans=0,l,r; srand(time(0)); treap.clear(); scanf("%lld",&n); for (i=1;i<=n;i++) { scanf("%lld %lld",&his,&opt); if (opt==1) { scanf("%lld %lld",&p,&x); p^=lastans; x^=lastans; treap.insert(his,i,p,x); } if (opt==2) { scanf("%lld",&p); p^=lastans; treap.erase(his,i,p); } if (opt==3) { scanf("%lld %lld",&l,&r); l^=lastans; r^=lastans; treap.rever(his,i,l,r); } if (opt==4) { scanf("%lld %lld",&l,&r); l^=lastans; r^=lastans; //cout<<l<<" "<<r<<endl; lastans=treap.query(his,i,l,r); printf("%lld ",lastans); } } return 0; }