【模板】区间翻转平衡树
emm,也是借大佬的板子来学习平衡树的。
原文:https://blog.csdn.net/a_comme_amour/article/details/79382104
测板子:https://www.lydsy.com/JudgeOnline/problem.php?id=3223
在洛谷也测了一遍,但是感觉点好少,于是上bzoj上再测测。。。,洛谷:https://www.luogu.org/problem/P3391
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=1e5+8; 4 const int inf=0x3f3f3f3f; 5 int rt,sz; 6 int a[N],f[N],ch[N][2],val[N],siz[N],tag[N]; 7 8 bool get(int x){ return ch[f[x]][1]==x;} 9 void update(int x){siz[x] = siz[ch[x][0]] + siz[ch[x][1]] + 1;} 10 void pushdown(int x){ 11 if( x && tag[x] ){ 12 tag[ch[x][1]]^=1; 13 tag[ch[x][0]]^=1; 14 swap(ch[x][1],ch[x][0]); 15 tag[x]=0; 16 } 17 } 18 void rotate(int x){ 19 int fa=f[x],ffa=f[fa],which=get(x); 20 pushdown(fa); pushdown(x); 21 ch[fa][which]=ch[x][which^1];f[ch[fa][which]]=fa; 22 ch[x][which^1]=fa;f[fa]=x; 23 f[x]=ffa; 24 if(ffa) ch[ffa][ch[ffa][1]==fa]=x; 25 update(fa); update(x); 26 } 27 void splay(int x,int goal){ 28 for(int fa; (fa=f[x])!=goal ;rotate(x) ){ 29 if(f[fa]!=goal) rotate( (get(x)==get(fa)) ? fa : x ); 30 } 31 if(!goal) rt=x; 32 } 33 int build(int fa,int l,int r){ 34 if(l>r) return 0; 35 int mid=(l+r)>>1; 36 int now=++sz; 37 val[now]=a[mid]; f[now]=fa; tag[now]=0; 38 ch[now][0]=build(now,l,mid-1); 39 ch[now][1]=build(now,mid+1,r); 40 update(now); 41 return now; 42 } 43 int find(int x){ 44 int now=rt; 45 while(1){ 46 pushdown(now); 47 if(x<=siz[ch[now][0]]) now=ch[now][0]; 48 else{ 49 x-=siz[ch[now][0]]+1; 50 if(!x) return now; 51 now=ch[now][1]; 52 } 53 } 54 } 55 void turn(int l,int r){ 56 l=find(l); 57 r=find(r+2); 58 splay(l,0); 59 splay(r,l); 60 pushdown(rt); 61 tag[ch[ch[rt][1]][0]]^=1; 62 } 63 void write(int x){ 64 pushdown(x); 65 if(ch[x][0]) write(ch[x][0]); 66 if(val[x]!=inf && val[x]!=-inf) printf("%d ",val[x]); 67 if(ch[x][1]) write(ch[x][1]); 68 } 69 int main(){ 70 int n,m;scanf("%d %d",&n,&m); 71 for(int i=2;i<=n+1;++i) a[i]=i-1; 72 a[1]=-inf;a[n+2]=inf; 73 rt=build(0,1,n+2); 74 for(int i=1;i<=m;++i){ 75 int x,y;scanf("%d %d",&x,&y); 76 turn(x,y); 77 } 78 write(rt); 79 return 0; 80 }