BZOJ3224 普通平衡树 with FHQ Treap 发表于 2017-01-03 | 更新于 2018-06-18 学了FHQTreap来试试模板,发现就这道题我的代码而言,比Treap和Scp慢,比Splay快。 当然一年过去了代码风格也有变化,等有空把各种平衡树的性能测试一番。 Code123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160//Code by Lucida#include<bits/stdc++.h>#define red(x) scanf("%d",&x)//#define debug(x) std::cout<<#x<<'='<<x<<std::endltemplate <class T> inline bool chkmx(T &a,const T &b){return a<b?a=b,1:0;}template <class T> inline bool chkmn(T &a,const T &b){return a>b?a=b,1:0;}const int MAXN=100000+10,P=1e5+7,INF=0x1f1f1f1f;using std::pair;using std::make_pair;struct TreapNode{ TreapNode *son[2]; int py,v,sz; void up(){sz=1+son[0]->sz+son[1]->sz;} int Rank(int); int LowCount(int); int Kth(int); int Pred(int); int Succ(int);}*null=new TreapNode,*root=null;typedef pair<TreapNode*,TreapNode*> NodePair;inline void InitTreap(){ null->son[0]=null->son[1]=null; null->py=P;null->sz=null->v=0;}inline TreapNode *newTreapNode(int v){ static TreapNode *ME=new TreapNode[MAXN],*cur; cur=ME++;cur->v=v;cur->son[0]=cur->son[1]=null; cur->py=rand()%P;cur->sz=1; return cur;}TreapNode *Merge(TreapNode *a,TreapNode *b){ if(a==null) return b; if(b==null) return a; if(a->py<b->py) { a->son[1]=Merge(a->son[1],b); a->up(); return a; } else//a->val>b->val { b->son[0]=Merge(a,b->son[0]); b->up(); return b; }}NodePair Split(TreapNode *pos,int K){ NodePair cur=make_pair(null,null); if(pos==null) return cur; if(K<=pos->son[0]->sz) { cur=Split(pos->son[0],K); pos->son[0]=cur.second,pos->up(); cur.second=pos; } else { cur=Split(pos->son[1],K-pos->son[0]->sz-1); pos->son[1]=cur.first,pos->up(); cur.first=pos; } return cur;}void Insert(int x){ NodePair sp=Split(root,root->LowCount(x)); root=Merge(Merge(sp.first,newTreapNode(x)),sp.second);}void Delete(int x){ NodePair sp1=Split(root,root->LowCount(x)), sp2=Split(sp1.second,sp1.second->Rank(x)); root=Merge(sp1.first,sp2.second);}int TreapNode::LowCount(int v){ TreapNode *pos=this; int res=0; while(pos!=null) { if(pos->v<v) { res+=pos->son[0]->sz+1; pos=pos->son[1]; } else pos=pos->son[0]; } return res;}int TreapNode::Rank(int v){return LowCount(v)+1;}int TreapNode::Kth(int K){ TreapNode *pos=this; while(pos!=null) { if(pos->son[0]->sz+1==K) return pos->v; else if(K<pos->son[0]->sz+1) pos=pos->son[0]; else K-=pos->son[0]->sz+1,pos=pos->son[1]; } return INF;}int TreapNode::Pred(int x){ TreapNode *pos=this; int res=-INF; while(pos!=null) { if(pos->v<x) { chkmx(res,pos->v); pos=pos->son[1]; } else pos=pos->son[0]; } return res;}int TreapNode::Succ(int x){ TreapNode *pos=this; int res=INF; while(pos!=null) { if(pos->v>x) { chkmn(res,pos->v); pos=pos->son[0]; } else pos=pos->son[1]; } return res;}int main(){ srand(0x1f1f1f1f); InitTreap(); //freopen("input","r",stdin); int n;red(n);int g=0; for(int i=1;i<=n;i++) { int opt,x;red(opt),red(x); switch(opt) { case 1:Insert(x);break; case 2:Delete(x);break; case 3:printf("%d\n",root->Rank(x));break; case 4:printf("%d\n",root->Kth(x));break; case 5:printf("%d\n",root->Pred(x));break; case 6:printf("%d\n",root->Succ(x));break; } } return 0;}