P3391 【模板】文艺平衡树(Splay)
题面
https://www.luogu.org/problem/P3391
题解
#include<cstdio> #include<iostream> using namespace std; const int start = 100050 ; struct node { int ch[2],fa; int v,siz; bool turn; } a[100500]; int n,m,cnt; bool opt(int x) { return a[a[x].fa].ch[1]==x; } void pushdown(int now) { if (!now || !a[now].turn) return; a[now].turn=false; swap(a[a[now].ch[0]].ch[0],a[a[now].ch[0]].ch[1]); a[a[now].ch[0]].turn^=1; swap(a[a[now].ch[1]].ch[0],a[a[now].ch[1]].ch[1]); a[a[now].ch[1]].turn^=1; } void rotate(int x) { int y=a[x].fa,z=a[y].fa; bool s=opt(x); pushdown(z); pushdown(y); pushdown(x); a[z].ch[opt(y)]=x; a[x].fa=z; a[y].ch[s]=a[x].ch[1^s]; a[a[x].ch[1^s]].fa=y; a[y].fa=x; a[x].ch[1^s]=y; a[y].siz=a[a[y].ch[0]].siz+a[a[y].ch[1]].siz+1; a[x].siz=a[a[x].ch[0]].siz+a[a[x].ch[1]].siz+1; } void splay(int now,int to) { while (a[now].fa!=to) { if (a[a[now].fa].fa==to) rotate(now); else { if (opt(now)==opt(a[now].fa)) rotate(a[now].fa),rotate(now); else rotate(now),rotate(now); } } } void insert(int x) { int now=start; while (a[now].ch[x>a[now].v]) a[now].siz++,now=a[now].ch[x>a[now].v]; a[now].siz++; a[now].ch[x>a[now].v]=++cnt; a[cnt]=(node){0,0,now,x,1,0}; splay(cnt,start); } int findbyrank(int rk) { int cnr=0,now=start; while (1) { pushdown(now); if (cnr+a[a[now].ch[0]].siz==rk) return now; else { if (cnr+a[a[now].ch[0]].siz>rk) now=a[now].ch[0]; else cnr+=a[a[now].ch[0]].siz+1,now=a[now].ch[1]; } } } void print(int now) { if (!now) return; pushdown(now); print(a[now].ch[0]); if (a[now].v>=1 && a[now].v<=n) printf("%d ",a[now].v); print(a[now].ch[1]); } int main(){ int i,l,r; scanf("%d %d",&n,&m); a[start]=(node){0,0,0,-1,1,0}; cnt=0; for (i=0;i<=n+1;i++) { //printf("%d\n",i); insert(i); } for (i=1;i<=m;i++) { //printf("%d\n",i); scanf("%d %d",&l,&r); int lx=findbyrank(l),rx=findbyrank(r+2); splay(lx,start); splay(rx,lx); swap(a[a[rx].ch[0]].ch[0],a[a[rx].ch[0]].ch[1]); a[a[rx].ch[0]].turn^=1; } print(start); }