BZOJ3224: Tyvj 1728 普通平衡树(无旋Treap/替罪羊)
来源:互联网 发布:appserv怎么进入mysql 编辑:程序博客网 时间:2024/05/29 10:26
传送门
题意:
平衡树的一系列操作。
题解:无旋Treap/替罪羊
作为一个用Splay水过无数道题的人,第一次写无旋Treap表示很慌。。
#include<bits/stdc++.h>using namespace std;typedef unsigned int uint;struct IO{ streambuf *ib,*ob; inline void init(){ ios::sync_with_stdio(false); cin.tie(NULL);cout.tie(NULL); ib=cin.rdbuf();ob=cout.rdbuf(); } inline int read(){ char ch=ib->sbumpc();int i=0,f=1; while(!isdigit(ch)){if(ch=='-')f=-1;ch=ib->sbumpc();} while(isdigit(ch)){i=(i<<1)+(i<<3)+ch-'0';ch=ib->sbumpc();} return i*f; } inline void W(long long x){ static int buf[50]; if(!x){ob->sputc('0');return;} if(x<0){ob->sputc('-');x=-x;} while(x)buf[++buf[0]]=x%10,x/=10; while(buf[0])ob->sputc(buf[buf[0]--]+'0'); } inline uint unit(){ static uint state0=23333; state0^=state0<<13; state0^=state0<<17; state0^=state0>>5; return state0; }}io;const int Maxn=1e5+50;int n;struct node{ node *lc,*rc; int sze,val; uint pri; node(); inline void upt(){ sze=lc->sze+rc->sze+1; }}Pool[Maxn],*pool=Pool,*null=Pool;node::node():lc(null),rc(null){}typedef pair<node*,node*> pii;struct RecyclePool{ node *que[Maxn]; int tail; inline node* newnode(int val){ static node* tmp; tmp=(tail?que[tail--]:++pool); tmp->lc=tmp->rc=null; tmp->sze=1;tmp->val=val;tmp->pri=io.unit(); return tmp; }}recyclepool;struct Treap{ node *rt; Treap():rt(null){} inline int getrank(int val){ node *tmp=rt;int k=0; if(tmp==null)return 0; while(tmp!=null){ if(tmp->val<val){k+=(tmp->lc->sze+1);tmp=tmp->rc;} else tmp=tmp->lc; } return k; } inline node* merge(node *x,node *y){ if(x==null)return y;if(y==null)return x; if(x->pri<y->pri){ x->rc=merge(x->rc,y);x->upt(); return x; } else{ y->lc=merge(x,y->lc);y->upt(); return y; } } inline pii split(node *now,int k){ if(now==null)return pii(null,null); if((now->lc->sze+1<=k)){ pii tr=split(now->rc,k-now->lc->sze-1); now->rc=tr.first;now->upt(); return pii(now,tr.second); } else{ pii tr=split(now->lc,k); now->lc=tr.second;now->upt(); return pii(tr.first,now); } } inline void insert(int val){ int k=getrank(val); pii tr=split(rt,k); node *tmp=recyclepool.newnode(val); rt=merge(merge(tr.first,tmp),tr.second); } inline void remove(int val){ int k=getrank(val); pii tr1=split(rt,k); pii tr2=split(tr1.second,1); rt=merge(tr1.first,tr2.second); recyclepool.que[++recyclepool.tail]=tr2.first; } inline int getkth(node *now,int k){ if(now->lc->sze+1<k)return getkth(now->rc,k-now->lc->sze-1); else if(now->lc->sze+1==k)return now->val; return getkth(now->lc,k); }}treap;int main(){ io.init();n=io.read(); for(int i=1;i<=n;i++){ int op=io.read(); if(op==1){treap.insert(io.read());} else if(op==2){treap.remove(io.read());} else if(op==3){io.W(treap.getrank(io.read())+1);io.ob->sputc('\n');} else if(op==4){io.W(treap.getkth(treap.rt,io.read()));io.ob->sputc('\n');} else if(op==5){io.W(treap.getkth(treap.rt,treap.getrank(io.read())));io.ob->sputc('\n');} else {io.W(treap.getkth(treap.rt,treap.getrank(io.read()+1)+1));io.ob->sputc('\n');} }}
写完替罪羊发现不重构可以过。。于是正解原来是二叉搜索树???
#include<bits/stdc++.h>using namespace std;const int alpha=75;struct IO{ streambuf *ib,*ob; inline void init(){ ios::sync_with_stdio(false); cin.tie(NULL);cout.tie(NULL); ib=cin.rdbuf();ob=cout.rdbuf(); } inline int read(){ char ch=ib->sbumpc();int i=0,f=1; while(!isdigit(ch)){if(ch=='-')f=-1;ch=ib->sbumpc();} while(isdigit(ch)){i=(i<<1)+(i<<3)+ch-'0';ch=ib->sbumpc();} return i*f; } inline void W(int x){ static int buf[50]; if(!x){ob->sputc('0');ob->sputc('\n');return;} if(x<0){ob->sputc('-');x=-x;} while(x){buf[++buf[0]]=x%10;x/=10;} while(buf[0]){ob->sputc(buf[buf[0]--]+'0');} ob->sputc('\n'); }}io;const int Maxn=1e5+50;int n;struct node{ node *lc,*rc; node():lc(NULL),rc(NULL){} int sze,val,cnt; inline void upt(){ sze=lc->sze+rc->sze+cnt; }}Pool[Maxn],*pool=Pool,*null=Pool,*rt=null;inline node* newnode(int val){ ++pool; pool->lc=pool->rc=null; pool->sze=pool->cnt=1;pool->val=val; return pool;}inline void insert_val(node*& now,int val,node**&p){ if(now==null){now=newnode(val);return;} if(val<now->val)insert_val(now->lc,val,p); else if(val>now->val)insert_val(now->rc,val,p); else now->cnt++; now->upt(); if(100*now->lc->sze>=now->sze*alpha||100*now->rc->sze>=now->sze*alpha)p=&now;}inline void erase_val(node*& now,int val,node **&p){ if(now->val==val)now->cnt--; else if(now->val<val)erase_val(now->rc,val,p); else erase_val(now->lc,val,p); now->upt(); if(100*now->lc->sze>=now->sze*alpha||100*now->rc->sze>=now->sze*alpha)p=&now;}node* que[Maxn];int tail=0;inline void traval(node *p){ if(p->lc->sze)traval(p->lc); if(p->cnt)que[++tail]=p; if(p->rc->sze)traval(p->rc);}inline node* build(int l,int r){ static int cnt; if(r<l)return null; if(l==r){ que[l]->lc=que[l]->rc=null; que[l]->sze=que[l]->cnt; return que[l]; } int mid=(l+r)>>1; node* tmp=que[mid]; tmp->lc=build(l,mid-1); tmp->rc=build(mid+1,r); tmp->upt(); return tmp;}inline void rebuild(node *&p){ tail=0;traval(p); int l=1,r=tail; p=build(l,r);}inline void insert(node*& now,int val){ node **p=&null; insert_val(now,val,p); if(*p!=null)rebuild(*p);}inline void del(node*& now,int val){ node **p=&null; erase_val(now,val,p); if(*p!=null)rebuild(*p);}inline int getrank(int val){ int k=0;node *tmp=rt; while(tmp!=null){ if(tmp->val<val)k+=tmp->lc->sze+tmp->cnt,tmp=tmp->rc; else tmp=tmp->lc; } return k+1;}inline int getkth(node *now,int kth){ if(now->lc->sze>=kth)return getkth(now->lc,kth); else if(now->lc->sze+now->cnt>=kth)return now->val; else return getkth(now->rc,kth-now->lc->sze-now->cnt);}inline int getpre(int val){ node *tmp=rt;int last; while(tmp!=null){ if(tmp->val>=val)tmp=tmp->lc; else last=tmp->val,tmp=tmp->rc; } return last;}inline int getsuf(int val){ node *tmp=rt;int last; while(tmp!=null){ if(tmp->val<=val)tmp=tmp->rc; else last=tmp->val,tmp=tmp->lc; } return last;}int main(){ io.init();n=io.read(); for(int i=1;i<=n;i++){ int op=io.read(); if(op==1){ insert(rt,io.read()); } else if(op==2){ del(rt,io.read()); } else if(op==3){ io.W(getrank(io.read())); } else if(op==4){ io.W(getkth(rt,io.read())); } else if(op==5){ io.W(getkth(rt,getrank(io.read())-1)); } else io.W(getkth(rt,getrank(io.read()+1))); }}
阅读全文
0 0
- BZOJ3224: Tyvj 1728 普通平衡树(无旋Treap/替罪羊)
- bzoj3224 Tyvj 1728 普通平衡树 ( 替罪羊树)
- [BZOJ3224]Tyvj 1728 普通平衡树 && treap
- bzoj3224 Tyvj 1728 普通平衡树 treap
- bzoj3224 Tyvj 1728 普通平衡树(splay/treap)
- 【模板】【bzoj3224】Tyvj 1728 普通平衡树 Treap
- bzoj3224 Tyvj 1728 普通平衡树 非旋转式Treap
- BZOJ3224[Tyvj 1728 普通平衡树]题解--Treap
- BZOJ3224 [Tyvj 1728] [普通平衡树] Treap的基本操作
- 无旋treap:从好奇到入门(例题:bzoj3224 普通平衡树)
- [Bzoj3224]Tyvj 1728 普通平衡树
- [BZOJ3224]Tyvj 1728 普通平衡树
- 【bzoj3224】Tyvj 1728 普通平衡树
- [BZOJ3224] Tyvj 1728 普通平衡树
- 【bzoj3224】Tyvj 1728 普通平衡树
- 【BZOJ3224】Tyvj 1728 普通平衡树
- bzoj3224: Tyvj 1728 普通平衡树
- bzoj3224 Tyvj 1728 普通平衡树
- C#梳理【索引器Indexer】
- Python实现个性化推荐一
- MySQL配置问题
- 2.基本套接字函数
- 在 Linux 中使用 Azure Premium 存储的基本优化指南
- BZOJ3224: Tyvj 1728 普通平衡树(无旋Treap/替罪羊)
- [MFC] RTTI应用总结(一)
- uboot烧写内核和文件系统
- Batch Normalization的前向和反向传播过程
- Servlet从入门开始学习(一)
- vue-Resource(与后端数据交互)
- java基于索引对List进行分批处理
- python中的number数字
- Tablayout+Viewpager+recyclerview简单实现