https://www.luogu.org/problemnew/show/P3391
知识点:1.split:1.拆数值 2.拆排名
2.merge
3.截取l - r这个区间,先截l - 1出来,再截 r - l +1(是r-l+1而不是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; } int siz[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; }