其实这题好久之前就做过了,毕竟比较水。
嗯很明显是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; }