BZOJ3223: Tyvj 1729 文艺平衡树
【传送门:BZOJ3223】
简要题意:
给出一个长度为n的序列,第i个数为i
给出多个操作,给出l,r,代表将序列中l到r的数翻转
然后输出最后的序列
题解:
SPLAY,注意在翻转一个区间后,要打个翻转标记,访问到儿子区间的时候要翻转一下
参考代码:
#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> using namespace std; struct node { int d,f,c,son[2]; bool fz; node(){fz=false;} }tr[110000];int root,len; void update(int x) { int lc=tr[x].son[0],rc=tr[x].son[1]; tr[x].c=tr[lc].c+tr[rc].c+1; } void rotate(int x,int w) { int f=tr[x].f,ff=tr[f].f; int R,r; R=f;r=tr[x].son[w]; if(r!=0)tr[r].f=R; tr[R].son[1-w]=r; R=ff;r=x; tr[r].f=R; if(tr[R].son[0]==f)tr[R].son[0]=r; else tr[R].son[1]=r; R=x;r=f; tr[r].f=R; tr[R].son[w]=r; update(f); update(x); } void weihufz(int x) { tr[x].fz=false; swap(tr[x].son[0],tr[x].son[1]); int lc=tr[x].son[0],rc=tr[x].son[1]; tr[lc].fz=1-tr[lc].fz; tr[rc].fz=1-tr[rc].fz; } void splay(int x,int rt) { while(tr[x].f!=rt) { int f=tr[x].f,ff=tr[f].f; if(ff==rt) { if(tr[x].fz==true)weihufz(f); if(tr[f].son[0]==x)rotate(x,1); else rotate(x,0); } else { if(tr[x].fz==true)weihufz(x); if(tr[f].fz==true){tr[f].fz=false;tr[x].fz=true;} if(tr[f].son[0]==x&&tr[ff].son[0]==f){rotate(f,1);rotate(x,1);} else if(tr[f].son[1]==x&&tr[ff].son[1]==f){rotate(f,0);rotate(x,0);} else if(tr[f].son[0]==x&&tr[ff].son[1]==f){rotate(x,1);rotate(x,0);} else if(tr[f].son[1]==x&&tr[ff].son[0]==f){rotate(x,0);rotate(x,1);} } } if(rt==0)root=x; } int ins(int l,int r) { if(l>r)return 0; int mid=(l+r)/2; len++;int now=len; tr[now].d=mid; int lc=ins(l,mid-1),rc=ins(mid+1,r); if(lc!=0)tr[lc].f=now; if(rc!=0)tr[rc].f=now; tr[now].son[0]=lc;tr[now].son[1]=rc; tr[now].c=tr[lc].c+tr[rc].c+1; return now; } int finddizhi(int k) { int x=root; while(1) { if(tr[x].fz==true)weihufz(x); int lc=tr[x].son[0],rc=tr[x].son[1]; if(k<=tr[lc].c)x=lc; else if(tr[lc].c+1<k){k-=tr[lc].c+1;x=rc;} else break; } return x; } void fanzhuan(int l,int r) { int lc=finddizhi(l-1),rc=finddizhi(r+1); splay(lc,0);splay(rc,lc); int x=tr[rc].son[0]; tr[x].fz=1-tr[x].fz; splay(x,0); } int a[110000],alen; void dfs(int x) { if(tr[x].fz==true)weihufz(x); int lc=tr[x].son[0],rc=tr[x].son[1]; if(lc==0&&rc==0){a[++alen]=tr[x].d;return ;} if(lc!=0)dfs(lc); a[++alen]=tr[x].d; if(rc!=0)dfs(rc); } int main() { int n,T,l,r; scanf("%d%d",&n,&T); root=ins(0,n+1); while(T--) { scanf("%d%d",&l,&r);l++;r++; fanzhuan(l,r); } alen=0;dfs(root); for(int i=2;i<alen-1;i++)printf("%d ",a[i]); printf("%d",a[alen-1]); return 0; }
渺渺时空,茫茫人海,与君相遇,幸甚幸甚