https://www.luogu.org/problemnew/show/P3391
Knowledge Point: 1.split:. 1 2. Remove the split numerical ranking
2.merge
3. Intercept l - r this interval, the first cut l - 1 out, and then cut r - l +1 (r-l + 1 is not r)
code:
#include <bits/stdc++.h> #define M 500002 using namespace std; int n,m,root; int tot = 0; int lazy[M]; int head[M],cnt; struct edge { int to; int nxt; }e[M * 2]; void add(int x,int y) { e[++cnt].nxt = head[x]; e[cnt].to = y; head[x] = cnt; } intsiz [M]; int ch [M] [ 2 ], val [M], rd [M]; void updata ( int x) { siz [x] = siz [ch [x] [ 0 ]] + siz [ch [x] [ 1 ]] + 1 ; } Int newnode ( int x) { val [ ++ tot] = x; rd [tot] = rand (); siz [tot] = 1 ; return tot; } Void down ( int x) { swap (ch [x] [ 0 ], ch [x] [ 1]); if(ch[x][0]) lazy[ch[x][0]] ^= 1; if(ch[x][1]) lazy[ch[x][1]] ^= 1; lazy[x] = 0; } void split(int now,int k,int &x,int &y) { if(!now) { x = y = 0; return; } else { if(lazy[now])down(now); if(siz[ch[now][0]] < k) { x = now; split(ch[now][1],k - siz[ch[now][0]] - 1,ch[now][1],y); } else { y = now; split(ch[now][0],k,x,ch[now][0]); } updata(now); } } int merge(int A,int B) { if(!A || !B)return A + B; if(rd[A] < rd[B]) { if(lazy[A])down(A); ch[A][1] = merge(ch[A][1],B); updata(A); return A; } else { if(lazy[B])down(B); ch[B][0] = merge(A,ch[B][0]); updata(B); return B; } } void work(int x,int y) { int a,b,c,d; split(root,x - 1,a,b); split(b,y - x + 1,b,c); lazy[b] ^= 1; root = merge(a,merge(b,c)); } void insert(int t) { root = merge(root,newnode(t)); } void print(int i) { if(!i) return; if(lazy[i]) down(i); print(ch[i][0]); printf("%d ",val[i]); print(ch[i][1]); } int main() { srand(1); scanf("%d%d",&n,&m); for(int i = 1;i <= n;i++)insert(i); int x,y; while(m--) { scanf("%d%d",&x,&y); work(x,y); } print(root); return 0; }