[普通平衡树]多种姿势 栽培小树苗
来源:互联网 发布:网络买古瓷咋卖 编辑:程序博客网 时间:2024/03/28 19:43
Splay 伸展树
#include<iostream>#include<cstdio>#include<cstring>using namespace std;#define pos(i,a,b) for(int i=(a);i<=(b);i++)#define N 100000int ch[N][3],size[N],w[N],v[N],fa[N];int root,sz;void clear(int x){ ch[x][0]=ch[x][1]=fa[x]=w[x]=v[x]=size[x]=0; } int get(int x){ return ch[fa[x]][1]==x; } void update(int x){ if (x){ size[x]=w[x]; if (ch[x][0]) size[x]+=size[ch[x][0]]; if (ch[x][1]) size[x]+=size[ch[x][1]]; } } void rotate(int x){ int old=fa[x],oldf=fa[old],which=get(x); ch[old][which]=ch[x][which^1];fa[ch[old][which]]=old; fa[old]=x;ch[x][which^1]=old; fa[x]=oldf; if (oldf) ch[oldf][ch[oldf][1]==old]=x; update(old);update(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){sz++;ch[sz][0]=ch[sz][1]=fa[sz]=0;size[sz]=w[sz]=1;v[sz]=x;root=sz;return;}int now=root,f=0;while(1){if(v[now]==x){w[now]++;update(now);update(f);splay(now);break;}f=now;now=ch[now][v[now]<x];if(!now){sz++;ch[sz][0]=ch[sz][1]=0;v[sz]=x;w[sz]=1;fa[sz]=f;ch[f][v[f]<x]=sz;update(f);splay(sz);break;}}}int find(int x){int ans=0,now=root;while(1){if(x<v[now]){now=ch[now][0];}else{ans+=(ch[now][0]?size[ch[now][0]]:0);if(x==v[now]){splay(now);return ans+1;}ans+=w[now];now=ch[now][1];}}}int findx(int x){int now=root;while(1){if(ch[now][0]&&x<=size[ch[now][0]]){now=ch[now][0];}else{int temp=(ch[now][0]?size[ch[now][0]]:0)+w[now];if(x<=temp)return v[now];x-=temp;now=ch[now][1];}}}int pre(){int now=ch[root][0];while(ch[now][1]) now=ch[now][1];return now;}void del(int x){int whatever=find(x);if(w[root]>1){w[root]--;return;}if(!ch[root][0]&&!ch[root][1]){clear(root);root=0;return;}if(!ch[root][0]){int oldroot=root;root=ch[root][1];fa[root]=0;clear(oldroot);return;}else{if(!ch[root][1]){int oldroot=root;root=ch[root][0];fa[root]=0;clear(oldroot);return;}}int leftbig=pre(),oldroot=root;splay(leftbig);fa[ch[oldroot][1]]=root;ch[root][1]=ch[oldroot][1];clear(oldroot);update(root);return;}int next(){int now=ch[root][1];while(ch[now][0]) now=ch[now][0];return now;} int main(){freopen("phs.in","r",stdin);freopen("phs.out","w",stdout);int n,opt,x; scanf("%d",&n); for (int i=1;i<=n;++i){ scanf("%d%d",&opt,&x); switch(opt){ case 1: insert(x); break; case 2: del(x); break; case 3: printf("%d\n",find(x)); break; case 4: printf("%d\n",findx(x)); break; case 5: insert(x); printf("%d\n",v[pre()]); del(x); break; case 6: insert(x); printf("%d\n",v[next()]); del(x); break; } } return 0;}
Treap 树
#include<iostream>#include<cstdlib>#include<cstdio>#include<cstring>using namespace std;#define pos(i,a,b) for(int i=(a);i<=(b);i++)#define pos2(i,a,b) for(int i=(a);i>=(b);i--)#define N 501000struct Treep{int l,r,w,v,size,rnd;}tree[N];int n;int root,size;void update(int k){tree[k].size=tree[tree[k].l].size+tree[tree[k].r].size+tree[k].w;}void lturn(int &k){int t=tree[k].r;tree[k].r=tree[t].l;tree[t].l=k;tree[t].size=tree[k].size;update(k);k=t;}void rturn(int &k){int t=tree[k].l;tree[k].l=tree[t].r;tree[t].r=k;tree[t].size=tree[k].size;update(k);k=t;}void insert(int &k,int x){if(k==0){size++;k=size;tree[k].w=tree[k].size=1;tree[k].v=x;tree[k].rnd=rand();return;}tree[k].size++;if(tree[k].v==x) tree[k].w++;else{if(tree[k].v<x){insert(tree[k].r,x);if(tree[tree[k].r].rnd<tree[k].rnd) lturn(k);}else{insert(tree[k].l,x);if(tree[tree[k].l].rnd<tree[k].rnd) rturn(k);}}}int tmp;void query_pro(int k,int x){if(k==0) return;if(tree[k].v<x){tmp=k;query_pro(tree[k].r,x);}else query_pro(tree[k].l,x);}void query_sub(int k,int x){if(k==0) return;if(tree[k].v>x){tmp=k;query_sub(tree[k].l,x);}else query_sub(tree[k].r,x);}void del(int &k,int x){if(k==0) return;if(tree[k].v==x){if(tree[k].w>1){tree[k].w--;tree[k].size--;return;}if(tree[k].l*tree[k].r==0) k=tree[k].l+tree[k].r;else{if(tree[tree[k].l].rnd<tree[k].rnd){rturn(k);del(k,x);}else{lturn(k);del(k,x);}}}else{if(tree[k].v<x){tree[k].size--;del(tree[k].r,x);}else{tree[k].size--;del(tree[k].l,x);}}}int query_rank(int k,int x){if(k==0) return 0;if(tree[k].v==x) return tree[tree[k].l].size+1;else{if(tree[k].v<x)return tree[tree[k].l].size+tree[k].w+query_rank(tree[k].r,x);else return query_rank(tree[k].l,x);}}int query_num(int k,int x){if(k==0) return 0;if(tree[tree[k].l].size>=x) return query_num(tree[k].l,x);else{if(tree[tree[k].l].size+tree[k].w<x) return query_num(tree[k].r,x-tree[tree[k].l].size-tree[k].w);else return tree[k].v;}}int main(){ freopen("phs.in","r",stdin); freopen("phs.out","w",stdout); scanf("%d",&n); int opt,x; pos(i,1,n){ scanf("%d%d",&opt,&x); switch(opt){ case 1:insert(root,x);break; case 2:del(root,x);break; case 3:printf("%d\n",query_rank(root,x));break; case 4:printf("%d\n",query_num(root,x));break; case 5:tmp=0;query_pro(root,x);printf("%d\n",tree[tmp].v);break; case 6:tmp=0;query_sub(root,x);printf("%d\n",tree[tmp].v);break; } } //while(1); return 0;}
无旋Treap
#include<iostream>#include<cstdio>#include<cstring>#include<cstdlib>#define inf 0x7fffffffusing namespace std;#define pos(i,a,b) for(int i=(a);i<=(b);i++)struct Treap{Treap *ch[2];int key,val,size;Treap(int v){size=1;val=v;key=rand();ch[0]=ch[1]=NULL;}void tain(){size=1+(ch[0]?ch[0]->size:0)+(ch[1]?ch[1]->size:0);}}*root;typedef pair<Treap*,Treap*> D;int size(Treap *o){return o?o->size:0;}Treap *merge(Treap *a,Treap *b){if(!a) return b;if(!b) return a;if(a->key < b->key){a->ch[1]=merge(a->ch[1],b);a->tain();return a;}else{b->ch[0]=merge(a,b->ch[0]);b->tain();return b;}}D split(Treap *o,int k){if(!o) return D(NULL,NULL);D y;if(size(o->ch[0])>=k){y=split(o->ch[0],k);o->ch[0]=y.second;o->tain();y.second=o;}else{y=split(o->ch[1],k-size(o->ch[0])-1);o->ch[1]=y.first;o->tain();y.first=o;}return y;}int getkth(Treap *o,int v){if(o==NULL) return 0;return (o->val >= v)?getkth(o->ch[0],v):getkth(o->ch[1],v)+size(o->ch[0])+1;}int findkth(int k){D x=split(root,k-1);D y=split(x.second,1);Treap *ans=y.first;root=merge(merge(x.first,ans),y.second);return ans!=NULL?ans->val:0;}void insert(int v){int k=getkth(root,v);D x=split(root,k);Treap *o=new Treap(v);root=merge(merge(x.first,o),x.second);}void del(int v){int k=getkth(root,v);D x=split(root,k);D y=split(x.second,1);root=merge(x.first,y.second);}int main(){freopen("phs.in","r",stdin);freopen("phs.out","w",stdout);int m,opt,x;scanf("%d",&m); while(m--) { scanf("%d%d",&opt,&x); switch(opt) { case 1:insert(x);break; case 2:del(x);break; case 3:printf("%d\n",getkth(root,x)+1);break; case 4:printf("%d\n",findkth(x));break; case 5:printf("%d\n",findkth(getkth(root,x)));break; case 6:printf("%d\n",findkth(getkth(root,x+1)+1));break; } } return 0;}
阅读全文
1 0
- [普通平衡树]多种姿势 栽培小树苗
- [Tyvj 1728]普通平衡树 5种姿势 (彩蛋)
- [BZOJ3224]普通平衡树
- 【bzoj3224】普通平衡树
- bzoj3224普通平衡树
- BZOJ3224普通平衡树
- 【bzoj1728】普通平衡树
- BZOJ3224 普通平衡树
- 【BZOJ3224】普通平衡树
- BZOJ3224普通平衡树
- Bzoj3224普通平衡树
- BZOJ3224 普通平衡树
- 普通平衡树 treap
- BZOJ3224 普通平衡树
- Treap-普通平衡树
- splay(普通平衡树)
- 普通平衡树
- BZOJ3224 普通平衡树
- springboot【9】数据访问之Spring-data-jpa
- 生成树计数
- Java解析Excel
- java垃圾回收机制
- FZU 1683 纪念SlingShot
- [普通平衡树]多种姿势 栽培小树苗
- Gym
- 数组的使用以及常见的方法
- 选择问题
- POJ 3061 Subsequence
- Hbase学习以及hbase下表的增删查操作
- HDU5631 Rikka with Graph
- mySQL查询数据库的内容
- flask数据库查询且排序