码迷,mamicode.com
首页 > 其他好文 > 详细

各种平衡树

时间:2017-12-02 12:52:11      阅读:123      评论:0      收藏:0      [点我收藏+]

标签:algorithm   uil   hid   dea   serve   pos   string   http   ace   

记一下自己写的平衡树

方便以后复制粘贴

题目链接

Vector

最快:284ms

技术分享图片
 1 #include<cstdio>
 2 #include<vector>
 3 #include<algorithm>
 4 using namespace std;
 5 const int MAXN=100005;
 6 vector<int>v;
 7 int n,opt,x;
 8 inline char nc()
 9 {
10     static char buf[MAXN],*p1=buf,*p2=buf;
11     return p1==p2&&(p2=(p1=buf)+fread(buf,1,MAXN,stdin),p1==p2)?EOF:*p1++;
12 }
13 inline int read()
14 {
15     char c=nc();int x=0,f=1;
16     while(c<0||c>9){if(c==-)f=-1;c=nc();}
17     while(c>=0&&c<=9){x=x*10+c-0;c=nc();}
18     return x*f;
19 }
20 int main()
21 {
22     v.reserve(100001);
23     n=read();
24     while(n--)
25     {
26         opt=read();x=read();
27         if(opt==1)    v.insert(lower_bound(v.begin(),v.end(),x),x);
28         if(opt==2)    v.erase (lower_bound(v.begin(),v.end(),x));
29         if(opt==3)    printf("%d\n",lower_bound(v.begin(),v.end(),x)-v.begin()+1);
30         if(opt==4)    printf("%d\n",v[x-1]);
31         if(opt==5)    printf("%d\n",v[lower_bound(v.begin(),v.end(),x)-v.begin()-1]);
32         if(opt==6)    printf("%d\n",v[upper_bound(v.begin(),v.end(),x)-v.begin()]);
33     }
34     return 0;
35 }
Vector

Splay

最快:128ms

技术分享图片
  1 #include<iostream>
  2 #include<cstdio>
  3 using namespace std;
  4 const int MAXN=1e6+10;
  5 const int maxn=0x7fffff;
  6 inline char nc()
  7 {
  8     static char buf[MAXN],*p1=buf,*p2=buf;
  9     return p1==p2&&(p2=(p1=buf)+fread(buf,1,MAXN,stdin),p1==p2)?EOF:*p1++;
 10 }
 11 inline int read()
 12 {
 13     char c=nc();int x=0,f=1;
 14     while(c<0||c>9){if(c==-)f=-1;c=nc();}
 15     while(c>=0&&c<=9){x=x*10+c-0;c=nc();}
 16     return x*f;
 17 }
 18 struct SPLAY
 19 {
 20 #define root tree[0].ch[1]
 21 struct node
 22 {
 23     int v,fa,ch[2],rec,sum;
 24 };
 25 node tree[MAXN];
 26 int pointnum,tot;
 27 SPLAY(){pointnum=tot=0;}
 28 int iden(int x){return tree[tree[x].fa].ch[0]==x?0:1;}
 29 inline void connect(int x,int fa,int how){tree[x].fa=fa;tree[fa].ch[how]=x;}
 30 inline void update(int x){tree[x].sum=tree[tree[x].ch[0]].sum+tree[tree[x].ch[1]].sum+tree[x].rec;}
 31 inline void rotate(int x)
 32 {
 33     int y=tree[x].fa;
 34     int R=tree[y].fa;
 35     int Rson=iden(y);
 36     int yson=iden(x);
 37     int b=tree[x].ch[yson^1];
 38     connect(b,y,yson);
 39     connect(y,x,yson^1);
 40     connect(x,R,Rson);
 41     update(y);update(x);
 42 }
 43 void splay(int pos,int to)// 把编号为pos的节点旋转到编号为to的节点 
 44 {
 45     to=tree[to].fa;
 46     while(tree[pos].fa!=to)
 47     {
 48         if(tree[tree[pos].fa].fa==to)    rotate(pos);
 49         else if(iden(tree[pos].fa)==iden(pos))    rotate(tree[pos].fa),rotate(pos);
 50         else    rotate(pos),rotate(pos);
 51     }
 52 }
 53 inline int newpoint(int v,int fa)//
 54 {
 55     tree[++tot].fa=fa;
 56     tree[tot].v=v;
 57     tree[tot].sum=tree[tot].rec=1;
 58     return tot;
 59 }
 60 inline void dele(int x)
 61 {
 62     tree[x].ch[0]=tree[x].ch[1]=0;
 63     if(x==tot)  tot--;
 64 }
 65 int find(int v)
 66 {
 67     int now=root;
 68     while(1)
 69     {
 70         if(tree[now].v==v)   {splay(now,root);return now;}
 71         int nxt=v<tree[now].v?0:1;
 72         if(!tree[now].ch[nxt])return 0;
 73         now=tree[now].ch[nxt];
 74     }
 75 }
 76 int build(int v)
 77 {
 78     pointnum++;
 79     if(tot==0){root=1;newpoint(v,0);}
 80     else
 81     {
 82         int now=root;
 83         while(1)
 84         {
 85             tree[now].sum++;
 86             if(tree[now].v==v){tree[now].rec++;return now;}//出现过
 87             int nxt=v<tree[now].v?0:1;
 88             if(!tree[now].ch[nxt])
 89             {
 90                 newpoint(v,now);
 91                 tree[now].ch[nxt]=tot;
 92                 return tot;
 93             }
 94             now=tree[now].ch[nxt];
 95         }
 96     }
 97     return 0;
 98 }
 99 inline void insert(int v)
100 {
101     int p=build(v);//p代表插到了哪里
102     splay(p,root);
103 }
104 void pop(int v)
105 {
106     int deal=find(v);
107     if(!deal)   return ;
108     pointnum--;
109     if(tree[deal].rec>1){tree[deal].rec--;tree[deal].sum--;return ;}
110     if(!tree[deal].ch[0])    root=tree[deal].ch[1],tree[root].fa=0;
111     else
112     {
113         int le=tree[deal].ch[0];
114         while(tree[le].ch[1])    le=tree[le].ch[1];
115         splay(le,tree[deal].ch[0]);
116         int ri=tree[deal].ch[1];
117         connect(ri,le,1);connect(le,0,1);
118         update(le);
119     }
120     dele(deal);
121 }
122 int rank(int v)// 查询值为v的数的排名 
123 {
124     int ans=0,now=root;
125     while(1)
126     {
127         if(tree[now].v==v)    return ans+tree[tree[now].ch[0]].sum+1;
128         if(now==0)  return 0;
129         if(v<tree[now].v)    now=tree[now].ch[0];
130         else                 ans+=tree[tree[now].ch[0]].sum+tree[now].rec,now=tree[now].ch[1];
131     }
132     if(now)    splay(now,root);
133     return 0;
134 }
135 int arank(int x)//查询排名为x的数是什么 
136 {
137     int now=root;
138     while(1)
139     {
140         int used=tree[now].sum-tree[tree[now].ch[1]].sum;
141         if(x>tree[tree[now].ch[0]].sum&&x<=used)    break;
142         if(x<used)    now=tree[now].ch[0];
143         else    x=x-used,now=tree[now].ch[1];
144     }
145     splay(now,root);
146     return tree[now].v;
147 }
148 int lower(int v)// 小于v的最大值 
149 {
150     int now=root;
151     int ans=-maxn;
152     while(now)
153     {
154         if(tree[now].v<v&&tree[now].v>ans)    ans=tree[now].v;
155         if(v>tree[now].v)    now=tree[now].ch[1];
156         else    now=tree[now].ch[0];
157     }
158     return ans;
159 }
160 int upper(int v)
161 {
162     int now=root;
163     int ans=maxn;
164     while(now)
165     {
166         if(tree[now].v>v&&tree[now].v<ans)    ans=tree[now].v;
167         if(v<tree[now].v)    now=tree[now].ch[0];
168         else    now=tree[now].ch[1];
169     }
170     return ans;
171 }
172 }s;
173 int main()
174 {
175     #ifdef WIN32
176     freopen("a.in","r",stdin);
177     #else
178     #endif
179     int n=read();
180     while(n--)
181     {
182         int opt=read(),x=read();
183         if(opt==1)    s.insert(x);
184         else if(opt==2)    s.pop(x);
185         else if(opt==3)    printf("%d\n",s.rank(x));
186         else if(opt==4)    printf("%d\n",s.arank(x));
187         else if(opt==5)    printf("%d\n",s.lower(x));
188         else if(opt==6)    printf("%d\n",s.upper(x));
189     }
190 } 
191 
192 Splay
Splay

FHQ Treap

最快:176ms

技术分享图片
  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<cmath>
  5 #include<algorithm>
  6 #include<cstdlib>
  7 #include<ctime>
  8 using namespace std;
  9 const int MAXN=1e6+10,INF=1e7;
 10 inline char nc()
 11 {
 12     static char buf[MAXN],*p1=buf,*p2=buf;
 13     return p1==p2&&(p2=(p1=buf)+fread(buf,1,MAXN,stdin),p1==p2)?EOF:*p1++;
 14 }
 15 inline int read()
 16 {
 17     char c=nc();int x=0,f=1;
 18     while(c<0||c>9){if(c==-)f=-1;c=nc();}
 19     while(c>=0&&c<=9){x=x*10+c-0;c=nc();}
 20     return x*f;
 21 }
 22 int ch[MAXN][3];// 0左孩子 1右孩子
 23 int val[MAXN];// 每一个点的权值
 24 int pri[MAXN];// 随机生成的附件权值
 25 int siz[MAXN];// 以i为节点的树的节点数量
 26 int sz;// 总结点的数量 
 27 void update(int x)
 28 {
 29     siz[x]=1+siz[ch[x][0]]+siz[ch[x][1]];
 30 } 
 31 int new_node(int v)
 32 {
 33     siz[++sz]=1;// 新开辟一个节点
 34     val[sz]=v;
 35     pri[sz]=rand(); 
 36     return sz;
 37 }
 38 int merge(int x,int y)// 合并 
 39 {
 40     if(!x||!y)    return x+y;// x和y中必定有一个是0
 41     if(pri[x]<pri[y])// 把x加到左边的树上 
 42     {
 43         ch[x][1]=merge(ch[x][1],y);// 不懂的看GIF图 
 44         update(x);
 45         return x;
 46     } 
 47     else
 48     {
 49         ch[y][0]=merge(x,ch[y][0]);
 50         update(y);
 51         return y;
 52     }
 53 }
 54 void split(int now,int k,int &x,int &y)
 55 {
 56     if(!now) x=y=0;// 到达叶子节点
 57     else
 58     {
 59         if(val[now]<=k)// 分离右子树    
 60             x=now,split(ch[now][1],k,ch[now][1],y);
 61         else 
 62             y=now,split(ch[now][0],k,x,ch[now][0]);
 63         update(now);
 64     } 
 65 }
 66 int kth(int now,int k)// 查询排名 
 67 {
 68     while(1)
 69     {
 70         if(k<=siz[ch[now][0]])
 71             now=ch[now][0];// 在左子树中,且数量小于左子树的大小,迭代寻找
 72         else if(k==siz[ch[now][0]]+1)
 73             return now;// 找到了
 74         else 
 75             k-=siz[ch[now][0]]+1,now=ch[now][1];// 去右子树找 
 76     }
 77 }
 78 int main()
 79 {
 80     srand((unsigned)time(NULL));
 81     int n;
 82     n=read();
 83     int root=0,x,y,z;
 84     for(int i=1;i<=n;i++)
 85     {
 86         int how=read(),a=read();        
 87         if(how==1)// 插入 
 88         {
 89             split(root,a,x,y);
 90             root=merge(merge(x,new_node(a)),y);
 91         }
 92         else if(how==2)//删除x 
 93         {
 94             split(root,a,x,z);
 95             split(x,a-1,x,y);
 96             y=merge(ch[y][0],ch[y][1]);
 97             root=merge(merge(x,y),z);
 98         }
 99         else if(how==3)//查询x的排名 
100         {
101             split(root,a-1,x,y);
102             printf("%d\n",siz[x]+1);
103             root=merge(x,y);
104         }
105         else if(how==4)// 查询排名为x的数 
106         {
107             printf("%d\n",val[kth(root,a)]);
108         }
109         else if(how==5)// 求x的前驱 
110         {
111             split(root,a-1,x,y);
112             printf("%d\n",val[kth(x,siz[x])]);
113             root=merge(x,y);
114         }
115         else if(how==6)// 求x的后继 
116         {
117             split(root,a,x,y);
118             printf("%d\n",val[kth(y,1)]);
119             root=merge(x,y);
120         }
121     }
122     return 0;
123 }
FHQ Treap

01 Trie树

最快:84ms

技术分享图片
 1 #include <cstdio>
 2 const int MAXN=1e6+10,INF=1e7;
 3 int ch[MAXN][2],num[MAXN],tot=2,root=1;
 4 inline char nc()
 5 {
 6     static char buf[MAXN],*p1=buf,*p2=buf;
 7     return p1==p2&&(p2=(p1=buf)+fread(buf,1,MAXN,stdin),p1==p2)?EOF:*p1++;
 8 }
 9 inline int read()
10 {
11     char c=nc();int x=0,f=1;
12     while(c<0||c>9){if(c==-)f=-1;c=nc();}
13     while(c>=0&&c<=9){x=x*10+c-0;c=nc();}
14     return x*f;
15 }
16 inline void insert(int x,int val)
17 {
18     x+=INF;
19     for(int i=25,now=root,t; ~i; i--)
20     {
21         if( !(ch[now][ t=x>>i &1 ]) )    ch[now][t]=++tot;
22         num[ now=ch[now][t] ]+=val;
23     }
24 }
25 inline int rak(int x)
26 {
27     x+=INF;
28     int ans=0;
29     for(int i=25,now=root,t; ~i ; i--)
30     {
31         if( (t=x>>i &1) )    
32             ans+=num[ ch[now][0] ];
33         now=ch[now][t];
34     }
35     return ans;
36 }
37 inline int kth(int x)
38 {
39     int ans=0;
40     for(int i=25,now=root; ~i ; i--)
41     {
42         if( x>num[ ch[now][0] ] )    ans|=1<<i,x-=num[ ch[now][0] ],now=ch[now][1];
43         else now=ch[now][0];
44     }
45     return ans-INF;
46 }
47 int main() 
48 {
49     #ifdef WIN32
50     freopen("a.in","r",stdin);
51     #else
52     #endif
53     int n=read();
54     while(n --) 
55     {
56         int x=read(),y=read();
57         if(x==1) insert(y, 1);
58         else if(x==2) insert(y, -1);
59         else if(x==3) printf("%d\n", rak(y) + 1);
60         else if(x==4) printf("%d\n", kth(y) );
61         else if(x==5) printf("%d\n", kth( rak(y) ) );
62         else if(x==6) printf("%d\n", kth( rak(y + 1) + 1) );
63     }
64 }
01 Trie树

Treap

最快:88ms

技术分享图片
  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstdlib>
  4 #define ls tree[k].l
  5 #define rs tree[k].r
  6 using namespace std;
  7 const int MAXN=1e6+10;
  8 inline char nc()
  9 {
 10     static char buf[MAXN],*p1=buf,*p2=buf;
 11     return p1==p2&&(p2=(p1=buf)+fread(buf,1,MAXN,stdin))?EOF:*p1++;
 12 }
 13 inline int read()
 14 {
 15     char c=nc();int x=0,f=1;
 16     while(c<0||c>9){if(c==-)f=-1;c=nc();}
 17     while(c>=0&&c<=9){x=x*10+c-0,c=nc();}
 18     return x*f;
 19 }
 20 struct node
 21 {
 22     int l,r,tot,recy,val,rd;
 23 }tree[MAXN];
 24 int size,root,ans=0;
 25 inline void update(int k)
 26 {
 27    tree[k].tot=tree[ls].tot+tree[rs].tot+tree[k].recy;
 28 }
 29 inline void insert(int &k,int x)
 30 {
 31     if(k==0)
 32     {
 33         ++size;k=size;
 34         tree[size].recy=tree[size].tot=1;
 35         tree[size].val=x;tree[size].rd=rand();return ;
 36     }
 37     tree[k].tot++;
 38     if(tree[k].val==x)    tree[k].recy++;
 39     else if(x < tree[k].val)    insert( ls, x);
 40     else insert( rs , x );
 41 }
 42 inline void LeftRotate(int &k)
 43 {
 44     int R=tree[k].r;
 45     tree[k].r=tree[R].l;
 46     tree[R].l=k;
 47     tree[R].tot=tree[k].tot;
 48     update(k);k=R;
 49 }
 50 inline void RightRotate(int &k)
 51 {
 52     int R=tree[k].l;
 53     tree[k].l=tree[R].r;
 54     tree[R].r=k;
 55     tree[R].tot=tree[k].tot;
 56     update(k);k=R;
 57 }
 58 inline void del(int &k,int x)
 59 {
 60     if(!k)    return ;
 61     if(tree[k].val==x)
 62     {
 63         if(tree[k].recy>1)    {tree[k].recy-=1,tree[k].tot-=1;return; }
 64         if(tree[k].l*tree[k].r==0)    k=tree[k].l+tree[k].r;
 65         else if(tree[ls].rd<tree[rs].rd)    RightRotate(k),del(k,x);
 66         else LeftRotate(k),del(k,x);
 67     }
 68     else if(x>tree[k].val)    tree[k].tot--,del(rs,x);
 69     else tree[k].tot--,del(ls,x);
 70 }
 71 int atrank(int &k,int x)
 72 {
 73     if(k==0)    return 0;
 74     if(tree[k].val==x)    return tree[ls].tot+1;
 75     if(tree[k].val<x)    return atrank(rs,x)+tree[ls].tot+tree[k].recy;
 76     else return atrank(ls,x);
 77 }
 78 int rerand(int k,int x)
 79 {
 80     if(k==0)    return 0;
 81     if(x<=tree[ls].tot)    return rerand(ls,x);
 82     else if(x>tree[ls].tot+tree[k].recy)    return rerand(rs,x-tree[ls].tot-tree[k].recy);
 83     else return tree[k].val;
 84 }
 85 void pred(int k,int x)
 86 {
 87     if(k==0) return ;
 88     if(tree[k].val<x)    ans=k,pred(rs,x);
 89     else pred(ls,x);
 90 }
 91 void succ(int &k,int x)
 92 {
 93     if(k==0) return ;
 94     if(tree[k].val>x)    ans=k,succ(ls,x);
 95     else succ(rs,x);
 96 }
 97 int main()
 98 {
 99     #ifdef WIN32
100     freopen("a.in","r",stdin);
101     #else
102     #endif
103     int n=read();
104     while(n--)
105     {
106         int opt=read(),x=read();ans=0;
107         if(opt==1)  insert(root,x);
108         if(opt==2)  del(root,x);
109         if(opt==3)  printf("%d\n",atrank(root,x));
110         if(opt==4)  printf("%d\n",rerand(root,x));
111         if(opt==5)  {pred(root,x);printf("%d\n",tree[ans].val);}
112         if(opt==6)  {succ(root,x);printf("%d\n",tree[ans].val);}
113     }
114 }
Treap

 

各种平衡树

标签:algorithm   uil   hid   dea   serve   pos   string   http   ace   

原文地址:http://www.cnblogs.com/zwfymqz/p/7953516.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!