模板—Splay
Posted al-ca
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了模板—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板子,不过不知道为啥常数稍大。
以上是关于模板—Splay的主要内容,如果未能解决你的问题,请参考以下文章