模板—Splay
#include<iostream> #include<cstring> #include<cstdio> #define LL long long using namespace std; struct Splay { struct node { int ch[2],fa,val,cnt,siz; #define l(x) tr[x].ch[0] #define r(x) tr[x].ch[1] #define fa(x) tr[x].fa #define val(x) tr[x].val #define cnt(x) tr[x].cnt #define siz(x) tr[x].siz }tr[1000010]; int sz,root; void clear(int x){fa(x)=l(x)=r(x)=val(x)=cnt(x)=siz(x)=0;} bool get(int x){return r(fa(x))==x;} int newnode(int x) { sz++;val(sz)=x;cnt(sz)=siz(sz)=1; fa(sz)=l(sz)=r(sz)=0;return sz; } void pushup(int x) { if(!x)return; siz(x)=cnt(x); if(l(x))siz(x)+=siz(l(x)); if(r(x))siz(x)+=siz(r(x)); } void rotate(int x) { int old=fa(x),oldf=fa(old),which=get(x); tr[old].ch[which]=tr[x].ch[which^1];fa(tr[old].ch[which])=old; tr[x].ch[which^1]=old;fa(old)=x;fa(x)=oldf; if(oldf)tr[oldf].ch[tr[oldf].ch[1]==old]=x; pushup(old);pushup(x); } void splay(int x) { for(int f;f=fa(x);rotate(x)) if(fa(f))rotate((get(x)==get(f))?f:x); root=x; } void insert(int x) { if(!root){root=newnode(x);return;} int now=root,fa=0; while(1) { if(x==val(now)){cnt(now)++,pushup(now),pushup(fa);splay(now);return;} fa=now,now=tr[now].ch[val(now)<x]; if(!now) { int tem=newnode(x); tr[fa].ch[x>val(fa)]=tem; fa(tem)=fa;val(tem)=x; pushup(fa);splay(tem);return; } } } int rnk(int x) { int now=root,ans=0; while(1) { if(x<val(now))now=l(now); else { ans+=siz(l(now)); if(x==val(now)){splay(now);return ans+1;} ans+=cnt(now);now=r(now); } } } int kth(int x) { int now=root; while(1) { if(l(now)&&x<=siz(l(now)))now=l(now); else { int tem=siz(l(now))+cnt(now); if(x<=tem)return val(now); x-=tem;now=r(now); } } } int pre(){int now=l(root);while(r(now))now=r(now);return now;} int nxt(){int now=r(root);while(l(now))now=l(now);return now;} void del(int x) { rnk(x); if(cnt(root)>1){cnt(root)--;pushup(root);return;} if(!l(root)&&!r(root)){clear(root);root=0;return;} if(!l(root)){int rt=root;root=r(rt);fa(root)=0;clear(rt);return;} if(!r(root)){int rt=root;root=l(rt);fa(root)=0;clear(rt);return;} int oldrt=root,leftbig=pre(); splay(leftbig);r(root)=r(oldrt); fa(r(oldrt))=root;clear(oldrt);pushup(root); } }T; signed main() { int n;cin>>n;int opt,x; for(int i=1;i<=n;i++) { cin>>opt>>x; if(opt==1)T.insert(x); if(opt==2)T.del(x); if(opt==3)cout<<T.rnk(x)<<endl; if(opt==4)cout<<T.kth(x)<<endl; if(opt==5){T.insert(x);cout<<T.val(T.pre())<<endl;T.del(x);} if(opt==6){T.insert(x);cout<<T.val(T.nxt())<<endl;T.del(x);} } }
一个封装比较好的splay板子,不过不知道为啥常数稍大。
UPD:又打了一个,还好点
#include<iostream> #include<cstring> #include<cstdio> #define LL long long using namespace std; struct Splay { #define N 300010 int ch[N][2],fa[N],siz[N],key[N],cnt[N]; int sz,rt; void clear(int x){ch[x][0]=ch[x][1]=fa[x]=siz[x]=key[x]=cnt[x]=0;} int get(int x){return ch[fa[x]][1]==x;} void pushup(int x) { if(!x)return;siz[x]=cnt[x]; if(ch[x][0])siz[x]+=siz[ch[x][0]]; if(ch[x][1])siz[x]+=siz[ch[x][1]]; } void rotate(int x) { int wh=get(x),f=fa[x],of=fa[f]; ch[f][wh]=ch[x][wh^1];fa[ch[f][wh]]=f; ch[x][wh^1]=f;fa[f]=x;fa[x]=of; if(of)ch[of][ch[of][1]==f]=x; pushup(f);pushup(x); } void splay(int x) { for(int f;f=fa[x];rotate(x)) if(fa[f])rotate((get(x)==get(f))?f:x); rt=x; } int node(int x){++sz,siz[sz]=cnt[sz]=1;key[sz]=x;fa[sz]=ch[sz][0]=ch[sz][1]=0;return sz;} void insert(int x) { if(!rt){rt=node(x);return;} int now=rt,f=0; while(1) { if(key[now]==x){cnt[now]++,pushup(now),pushup(f);splay(now);return;} f=now;now=ch[now][x>key[now]]; if(!now) { int tem=node(x);ch[f][x>key[f]]=tem; fa[tem]=f;pushup(f);pushup(tem);splay(tem);return; } } } int kth(int k) { int p=rt; while(1) { if(ch[p][0]&&siz[ch[p][0]]>=k)p=ch[p][0]; else if(siz[ch[p][0]]+cnt[p]>=k)return key[p]; else k-=siz[ch[p][0]]+cnt[p],p=ch[p][1]; } } int rnk(int x) { int p=rt,al=0; while(1) { if(x<key[p])p=ch[p][0]; else { al+=siz[ch[p][0]]; if(x==key[p]){splay(p);return al+1;} al+=cnt[p];p=ch[p][1]; } } } int pre(){int now=ch[rt][0];while(ch[now][1])now=ch[now][1];return now;} int nxt(){int now=ch[rt][1];while(ch[now][0])now=ch[now][0];return now;} void del(int x) { rnk(x); if(cnt[rt]>1){cnt[rt]--;pushup(rt);return;} if(!ch[rt][0]&&!ch[rt][1]){clear(rt);rt=0;return;} if(!ch[rt][0]){int root=rt;rt=ch[rt][1];fa[rt]=0;clear(root);return;} if(!ch[rt][1]){int root=rt;rt=ch[rt][0];fa[rt]=0;clear(root);return;} int oldrt=rt,leftbig=pre(); splay(leftbig);ch[rt][1]=ch[oldrt][1]; fa[ch[oldrt][1]]=rt;clear(oldrt);pushup(rt); } }T; signed main() { int n;cin>>n;int opt,x; for(int i=1;i<=n;i++) { cin>>opt>>x; if(opt==1)T.insert(x); if(opt==2)T.del(x); if(opt==3)cout<<T.rnk(x)<<endl; if(opt==4)cout<<T.kth(x)<<endl; if(opt==5){T.insert(x);cout<<T.key[T.pre()]<<endl;T.del(x);} if(opt==6){T.insert(x);cout<<T.key[T.nxt()]<<endl;T.del(x);} } }
波澜前,面不惊。