[普通平衡树]多种姿势 栽培小树苗

来源:互联网 发布:网络买古瓷咋卖 编辑:程序博客网 时间: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;}