3223: Tyvj 1729 文艺平衡树

来源:互联网 发布:淘宝服装店铺策划书 编辑:程序博客网 时间:2024/05/29 02:11

其实这题好久之前就做过了,毕竟比较水。

嗯很明显是Splay

不过啊

竞赛中有两种常用的平衡树。

1是Splay,2呢,就是Treap了。

于是我今天刚好看见了一个很奇怪的东西。

传说中的非旋转Treap,不过好像只能解决区间问题。

PS:有Splay还要这个干嘛?我真是闲啊。而且这个好像跑得比Splay慢一点。。。。

#include<iostream>#include<cstdio>#include<cstring>#include<cstdlib>#include<ctime>#include<algorithm>#include<cctype>using namespace std;template<class T>void read(T &x){static char c;static bool f;for(f=0;c=getchar(),!isdigit(c);)if(c=='-')f=1;for(x=0;isdigit(c);c=getchar())x=x*10+c-'0';if(f)x=-x;}const int N=100000+10;typedef pair<int,int>droot;int rnd[N],key[N],sz[N],lc[N],rc[N],root,cnt;bool rev[N];void pushup(int x){sz[x]=sz[lc[x]]+sz[rc[x]]+1;}void pushdown(int x){if(rev[x]){rev[x]^=1;rev[lc[x]]^=1;rev[rc[x]]^=1;swap(lc[x],rc[x]);}}int merge(int x,int y){if(!x||!y)return x+y;if(rnd[x]<rnd[y]){pushdown(x);rc[x]=merge(rc[x],y);pushup(x);return x;}else{pushdown(y);lc[y]=merge(x,lc[y]);pushup(y);return y;}}droot split(int x,int k){if(!x)return droot(0,0);droot y;pushdown(x);if(k<=sz[lc[x]]){y=split(lc[x],k);lc[x]=y.second;y.second=x;}else{y=split(rc[x],k-sz[lc[x]]-1);rc[x]=y.first;y.first=x;}pushup(x);return y;}int n,st[N];int build(){int x,last;int p=0;for(int i=0;i<=n+1;i++){x=++cnt;rnd[x]=rand();key[x]=i;sz[x]=1;lc[x]=rc[x]=0;last=0;while(p&&rnd[st[p]]>rnd[x]){pushup(st[p]);last=st[p];st[p--]=0;}if(p)rc[st[p]]=x;lc[x]=last;st[++p]=x;}while(p)pushup(st[p--]);return st[1];}int kth(int k){droot x=split(root,k-1);droot y=split(x.second,1);int ans=y.first;root=merge(merge(x.first,ans),y.second);return key[ans];}int rank(int x,int v){if(!x)return 0;if(v<key[x])return rank(lc[x],v);else return sz[lc[x]]+1+rank(rc[x],v);}void insert(int v){int k=rank(root,v);droot x=split(root,k);int y=++cnt;rnd[y]=rand();key[y]=v;sz[y]=1;lc[y]=rc[y]=0;root=merge(merge(x.first,y),x.second);}void del(int k){droot x=split(root,k-1);droot y=split(root,1);root=merge(x.first,y.second);}void print(int x){if(!x)return;pushdown(x);print(lc[x]);if(key[x]>0&&key[x]<=n)printf("%d ",key[x]);print(rc[x]);}void rever(int l,int r){droot x=split(root,l);droot y=split(x.second,r-l+1);rev[y.first]^=1;root=merge(merge(x.first,y.first),y.second);}int main(){srand(1453031943);int m;read(n);read(m);root=build();int l,r;while(m--){read(l);read(r);rever(l,r);}print(root);return 0;}


0 0