[bzoj3223]Tyvj 1729 文艺平衡树
来自FallDream的博客,未经允许,请勿转载,谢谢。
一个序列,一开始是1到n,需要支持翻转区间,输出最后的结果。 n,m<=10^5
splay/无旋Treap
补了一下无旋Treap 顺便yy了一下笛卡尔树的建法,然后lazytag的实现也挺好想的。
#include<iostream> #include<cstdio> #define MN 100000 #define Size(x) (x?x->sz:0) using namespace std; inline int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();} return x*f; } inline int Ran() { static int x=23333; x^=(x<<13);x^=(x>>17);x^=(x<<5); return x; } struct Treap { Treap *l,*r; int sz,x,k;bool rev; Treap(){l=r=NULL;} Treap(int key){x=key;k=Ran();sz=1;l=r=NULL;} void update(){sz=Size(l)+Size(r)+1;} void pushdown() { if(rev) { l?l->rev^=1:0; r?r->rev^=1:0; rev^=1;swap(l,r); } } }*rt; typedef pair<Treap*,Treap*> D; int n,m,top=0; Treap* Merge(Treap*x,Treap*y) { if(!x)return y; if(!y)return x; if(x->k<y->k) { x->pushdown(); x->r=Merge(x->r,y); return x->update(),x; } else { y->pushdown(); y->l=Merge(x,y->l); return y->update(),y; } } D Split(Treap*x,int Rk) { if(!x) return D(NULL,NULL); D b;x->pushdown(); if(Size(x->l)>=Rk) { b=Split(x->l,Rk); x->l=b.second; x->update(); b.second=x; } else { b=Split(x->r,Rk-Size(x->l)-1); x->r=b.first; x->update(); b.first=x; } return b; } Treap*q[MN+5],*a[MN+5],*last; Treap* build() { for(int i=1;i<=n;i++) { last=NULL; while(top&&a[i]->k>q[top]->k) q[top]->update(),last=q[top],q[top--]=NULL; if(top) q[top]->r=a[i]; q[++top]=a[i];q[top]->l=last; } for(;top;--top) q[top]->update(); return q[1]; } void Dfs(Treap*x) { x->pushdown(); if(x->l) Dfs(x->l); printf("%d ",x->x); if(x->r) Dfs(x->r); } int main() { n=read();m=read(); for(int i=1;i<=n;i++)a[i]=new Treap(i); rt=build(); for(int i=1;i<=m;i++) { int l=read(),r=read(); D a=Split(rt,l-1); D b=Split(a.second,r-l+1); b.first->rev^=1; rt=Merge(Merge(a.first,b.first),b.second); } Dfs(rt); return 0; }
FallDream代表秋之国向您问好!
欢迎您来我的博客www.cnblogs.com/FallDream