平衡树(splay treap)(普通平衡树,郁闷的出纳员)
2017-06-19 19:11
288 查看
splay模板
普通平衡树
treap模板
普通平衡树
郁闷的出纳员
普通平衡树
#include<cstdio> #include<iostream> #define MAXN 100005 int size,tcnt,root; struct tree{ int val,sz,cnt; int s[2],fa; }; tree t[MAXN]; bool son(int x) { return t[t[x].fa].s[1] == x;//rc:1,lc:0 } void rejs(int x) { t[x].sz = t[t[x].s[0]].sz + t[t[x].s[1]].sz + t[x].cnt; } void point(int x,int fa,bool z) { if(x)t[x].fa=fa; if(fa)t[fa].s[z]=x; else root=x; } void rotnate(int x) { int y=t[x].fa; int z=t[y].fa; bool yy=son(y),xx=son(x); point(t[x].s[!xx],y,xx); point(y,x,!xx); point(x,z,yy); rejs(y); rejs(x); } //void rotnate(int x) // { // int y=t[x].fa,z=t[y].fa; // bool xType=son(x),yType=son(y); // point(t[x].s[!xType],y,xType); // point(y,x,!xType); // point(x,z,yType); // rejs(y);rejs(x); // } void splay(int x,int toFa) { while(t[x].fa!=toFa) { int xFa=t[x].fa; if(t[xFa].fa==toFa) rotnate(x); else { if(son(xFa)==son(x)) {rotnate(xFa);rotnate(x);} else {rotnate(x);rotnate(x);} } } } int find(int val) { int x=root; while(x) { if(t[x].val==val)return x; if(t[x].val<val)x=t[x].s[1]; else x=t[x].s[0]; } return 0; } int stmax(int x) { int y=0; while(x) { y=x; x=t[x].s[1]; } return y; } int stmin(int x) { int y=0; while(x) { y=x; x=t[x].s[0]; } return y; } void insert(int val) { ++size; int x=root,y=0; while(x) { y=x; if(t[x].val==val) { ++t[x].cnt; splay(x,0); return ; } if(val<t[x].val)x=t[x].s[0]; else x=t[x].s[1]; } x=++tcnt; t[x].val=val; t[x].fa=y; t[x].cnt=t[x].sz=1; point(x,y,val>t[y].val); splay(x,0); } void erase(int val) { --size; int x=find(val); if(!x) { return; } if(t[x].cnt>1) { --t[x].cnt; splay(x,0); return; } splay(x,0); int y=stmax(t[x].s[0]); int z=stmin(t[x].s[1]);for(;;); if((!y)&&(!z)) size=0,root=0; else if(!y) { splay(z,0); t[z].s[0]=0; rejs(z); } else if(!z) { splay(y,0); t[z].s[1]=0; rejs(y); } else { splay(y,0); splay(z,y); t[z].s[0]=0; rejs(z); rejs(y); } } int lower(int val) { int x=root,y=0; while(x) { if(val>t[x].val)y=x,x=t[x].s[1]; else x=t[x].s[0]; } return t[y].val; } int upper(int val) { int x=root,y=0; while(x) { if(val<t[x].val)y=x,x=t[x].s[0]; else x=t[x].s[1]; } return t[y].val; } int rank1(int val) { insert(val); int ret=t[t[root].s[0]].sz+1; erase(val); return ret; } int rank2(int rank) { int x=root; while(rank>t[t[x].s[0]].sz+t[x].cnt||rank<=t[t[x].s[0]].sz 4000 ) { if(rank<=t[t[x].s[0]].sz) x=t[x].s[0]; else rank-=t[t[x].s[0]].sz+t[x].cnt,x=t[x].s[1]; } return t[x].val; } int main() { int n,op,b; scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d%d",&op,&b); if(op==1)insert(b); if(op==2)erase(b); if(op==3)printf("%d\n",rank1(b)); if(op==4)printf("%d\n",rank2(b)); if(op==5)printf("%d\n",lower(b)); if(op==6)printf("%d\n",upper(b)); } }
treap模板
普通平衡树
#include<cstdio> #include<iostream> #include<ctime> #include<algorithm> using namespace std; int root,n,a,b,tmp; int sz; struct treap{ int sz,tot,w,rnd,ch[2]; int lc,rc; }t[1000500]; void update(int x) { t[x].sz=t[t[x].ch[0]].sz+t[t[x].ch[1]].sz+t[x].tot; } void turn(int &x,int k) { int y=t[x].ch[k^1]; t[x].ch[k^1]=t[y].ch[k]; t[y].ch[k]=x; update(x); update(y); x=y; } void insert(int &x,int w) { if(!x) { t[++sz].w=w; t[sz].rnd=rand(); t[sz].tot=t[sz].sz=1; x=sz; } else { if(t[x].sz++,t[x].w==w)t[x].tot++; else if(insert(t[x].ch[tmp=w>t[x].w],w),t[t[x].ch[tmp]].rnd>t[x].rnd) { turn(x,tmp^1); } } } void del(int &x,int w) { if(!x)return; if(t[x].w==w) { if(t[x].tot>1)t[x].tot--,t[x].sz--; else { if(!(t[x].ch[0]&&t[x].ch[1]))x=t[x].ch[0]|t[x].ch[1]; else turn(x,tmp=t[t[x].ch[0]].rnd>t[t[x].ch[1]].rnd),t[x].sz--,del(t[x].ch[tmp],w); } } else t[x].sz--,del(t[x].ch[w>t[x].w],w); } int rank1(int x,int w) { if(t[x].w==w)return t[t[x].ch[0]].sz+1; if(t[x].w<w)return t[t[x].ch[0]].sz+t[x].tot+rank1(t[x].ch[1],w); else return rank1(t[x].ch[0],w); } int kth(int x,int w) { if(!x)return 0; if(w<=t[t[x].ch[0]].sz)return kth(t[x].ch[0],w); else if(w>t[t[x].ch[0]].sz+t[x].tot)return kth(t[x].ch[1],w-t[t[x].ch[0]].sz-t[x].tot); else return t[x].w; } int pre(int v) { insert(root,v); tmp=kth(root,rank1(root,v)-1); del(root,v); return tmp; } int find(int x,int v) { return t[x].w==v?x:find(t[x].ch[t[x].w<v],v); } int sub(int v) { insert(root,v); tmp=kth(root,rank1(root,v)+t[find(root,v)].tot); del(root,v); return tmp; } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d%d",&a,&b); if(a==1)insert(root,b); if(a==2)del(root,b); if(a==3)printf("%d\n",rank1(root,b)); if(a==4)printf("%d\n",kth(root,b)); if(a==5)printf("%d\n",pre(b)); if(a==6)printf("%d\n",sub(b)); } }
郁闷的出纳员
#include<cstdio> #include<iostream> #include<ctime> #include<algorithm> using namespace std; int lim,n,m; char c[2]; struct treap{ int sz,w,rnd; int ch[2]; }t[100005]; int delet,sz,root,tmp; //void update(int x) //{ // t[x].sz=t[t[x].ch[0]].sz+t[t[x].ch[1]].sz+1; //} void update(int k) { t[k].sz=t[t[k].ch[0]].sz+t[t[k].ch[1]].sz+1; } void turn(int &x,int k) { int y=t[x].ch[k^1]; t[x].ch[k^1]=t[y].ch[k]; t[y].ch[k]=x; update(x); update(y); x=y; } //void rturn(int &k) // { // int l=t[k].ch[0]; // t[k].ch[0]=t[l].ch[1]; // t[l].ch[1]=k; // t[l].sz=t[k].sz; // update(k); // k=l; // } //void lturn(int &k) // { // int l=t[k].ch[1]; // t[k].ch[1]=t[l].ch[0]; // t[l].ch[0]=k; // t[l].sz=t[k].sz; // update(k); // k=l; // } void insert(int &x,int w) { if(!x) { t[++sz].w=w; t[sz].rnd=rand(); t[sz].sz=1; x=sz; } else { //if(t[x].sz++,t[x].w==w)t[x].tot++; t[x].sz++; insert(t[x].ch[tmp=w>t[x].w],w); if(t[t[x].ch[tmp]].rnd>t[x].rnd) turn(x,tmp^1); } } //void insert(int &k,int x) // { // if (k==0) // { // sz++; // k=sz; // t[k].w=x; // t[k].rnd=rand(); // t[k].sz=1; // return; // } // t[k].sz++; // if (x<t[k].w) // { // insert(t[k].ch[0],x); // if (t[t[k].ch[0]].rnd<t[k].rnd) rturn(k); // } // else // { // insert(t[k].ch[1],x); // if (t[t[k].ch[1]].rnd<t[k].rnd) lturn(k); // } // } int del(int &x,int w) { int dt; if(!x)return 0; // if(t[x].w==w) // { // if(t[x].tot>1)t[x].tot--; // else if(!(t[x].ch[0]&&t[x].ch[1]))x=t[x].ch[0]|t[x].ch[1]; // else turn(x,tmp=t[t[x].ch[0]].rnd>t[t[x].ch[1]].rnd),t[x].sz--; // } // else t[x].sz--,del(t[x].ch[w>t[x].w],w); if(t[x].w<w) { dt=t[t[x].ch[0]].sz+1; x=t[x].ch[1]; return dt+del(x,w); } else { dt=del(t[x].ch[0],w); t[x].sz-=dt; return dt; } } //int del(int &k,int x) // { // int dt; // if (k==0) return 0; // if (t[k].w<x) // { // dt=t[t[k].ch[0]].sz+1; // k=t[k].ch[1]; // return dt+del(k,x); // } // else // { // dt=del(t[k].ch[0],x); // t[k].sz-=dt; // return dt; // } // } //int rank1(int x,int w) //{ // if(t[x].w==w)return t[t[x].ch[0]].sz+1; // if(t[x].w<w)return rank1(t[x].ch[1],w)+t[t[x].ch[0]].sz+1; // else return rank1(t[x].ch[0],w); //} int kth(int x,int w) { if(!x)return 0; if(t[t[x].ch[0]].sz+1<w)return kth(t[x].ch[1],w-t[t[x].ch[0]].sz-1); else if(t[t[x].ch[0]].sz+1>w)return kth(t[x].ch[0],w); else return t[x].w+delet; } //int find (int k,int x) // { // if (t[t[k].ch[0]].sz+1==x) return t[k].w+delet; // else if (t[t[k].ch[0]].sz+1<x) return find(t[k].ch[1],x-t[t[k].ch[0]].sz-1); // else return find(t[k].ch[0],x); //} int main() { int res; scanf("%d%d",&n,&lim); for(int i=1;i<=n;i++) { int x; scanf("%s%d",c,&x); switch(c[0]) { case 'I': if (x>=lim) insert(root,x-delet);break; case 'A': delet+=x;break; case 'S':delet-=x; res+=del(root,m-delet); break; case 'F':if (x>t[root].sz) printf("-1\n"); else printf("%d\n",kth(root,t[root].sz-x+1)); } } printf("%d\n",res); } //int main() // { // int leave; // srand(time(0)); // scanf("%d%d",&n,&m); // for (int i=0;i<n;i++) // { // char ch[2]; // int x; // scanf("%s%d",ch,&x); // switch(ch[0]) // { // case 'I': if (x>=m) insert(root,x-delet);break; // case 'A': delet+=x;break; // case 'S':delet-=x; leave+=del(root,m-delet); break; // case 'F':if (x>t[root].sz) printf("-1\n"); // else // printf("%d\n",find(root,t[root].sz-x+1)); // } // } // printf("%d\n",leave); // }
相关文章推荐
- 【模板】普通平衡树(Treap/SBT) 洛谷 3369 splay
- 【模板】bzoj-3224普通平衡树(splay&treap&SBT)
- [BZOJ 3224]普通平衡树(忽然想要存个模板 Treap/Splay)
- 郁闷的出纳员——动态统计(Treap,ST,Splay,BIT)
- bzoj 1503 [NOI2004]郁闷的出纳员 平衡树(treap/Splay)
- Splay练习1——P3369 【模板】普通平衡树(Treap/SBT)
- 【Splay|Treap】poj3580 SuperMemo && bzoj1503 [noi2004]郁闷的出纳员
- HYSBZ - 1503 : 郁闷的出纳员 (Treap 平衡树)
- [BZOJ1503][NOI2004]郁闷的出纳员(平衡树splay)
- BZOJ 1503 郁闷的出纳员 二叉平衡树(Treap,Splay)
- 【bzoj3224】Tyvj 1728 普通平衡树 01Trie姿势+平衡树的四种姿势 :splay,旋转Treap,非旋转Treap,替罪羊树
- BZOJ3224:普通平衡树(含SBT、Treap、Splay模板)
- [BZOJ1503][NOI2004]郁闷的出纳员(平衡树splay)
- bzoj 1503: [NOI2004]郁闷的出纳员 平衡树treap
- 数组splay ------ luogu P3369 【模板】普通平衡树(Treap/SBT)
- BZOJ3224:普通平衡树(含SBT、Treap、Splay模板)
- 普通平衡树 treap
- [普通平衡树splay]【学习笔记】
- 【例题】【Splay】NKOJ1921 郁闷的出纳员
- 【BZOJ 3224】普通平衡树-Splay