bzoj3224 Tyvj 1728 普通平衡树

Description

您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
1. 插入x数
2. 删除x数(若有多个相同的数,因只删除一个)
3. 查询x数的排名(若有多个相同的数,因输出最小的排名)
4. 查询排名为x的数
5. 求x的前驱(前驱定义为小于x,且最大的数)
6. 求x的后继(后继定义为大于x,且最小的数)

Input

第一行为n,表示操作的个数,下面n行每行有两个数opt和x,opt表示操作的序号(1<=opt<=6)

Output

对于操作3,4,5,6每行输出一个数,表示对应答案

Sample Input

10
1 106465
4 1
1 317721
1 460929
1 644985
1 84185
1 89851
6 81968
1 492737
5 493598

Sample Output

106465
84185
492737

HINT

1.n的数据范围:n<=100000
2.每个数的数据范围:[-1e7,1e7]
数据如下http://pan.baidu.com/s/1jHMJwO2

正解:平衡树。

这题就是平衡树,各种平衡树都能写。。今天晚上学了学替罪羊树,我能说我调了一晚上的原因是因为insert的传址问题吗。。

 

替罪羊树:

  1 //It is made by wfj_2048~
  2 #include <algorithm>
  3 #include <iostream>
  4 #include <complex>
  5 #include <cstring>
  6 #include <cstdlib>
  7 #include <cstdio>
  8 #include <vector>
  9 #include <cmath>
 10 #include <queue>
 11 #include <stack>
 12 #include <map>
 13 #include <set>
 14 #define N (100010)
 15 #define il inline
 16 #define RG register
 17 #define ll long long
 18 #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
 19 
 20 using namespace std;
 21 
 22 int ch[N][2],cover[N],sz[N],val[N],del[N],st[N],Q,rt,top,tot;
 23 const double alpha=0.75;
 24 
 25 il int gi(){
 26     RG int x=0,q=1; RG char ch=getchar(); while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
 27     if (ch=='-') q=-1,ch=getchar(); while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar(); return q*x;
 28 }
 29 
 30 il void pushup(RG int x){
 31     sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+(!del[x]);
 32     cover[x]=cover[ch[x][0]]+cover[ch[x][1]]+1; return;
 33 }
 34 
 35 il void dfs(RG int x){
 36     if (ch[x][0]) dfs(ch[x][0]);
 37     if (!del[x]) st[++top]=x;
 38     if (ch[x][1]) dfs(ch[x][1]);
 39     sz[x]=cover[x]=ch[x][0]=ch[x][1]=0;
 40     return;
 41 }
 42 
 43 il int divide(RG int l,RG int r){
 44     if (l>r) return 0; RG int mid=(l+r)>>1;
 45     ch[st[mid]][0]=divide(l,mid-1);
 46     ch[st[mid]][1]=divide(mid+1,r);
 47     pushup(st[mid]); return st[mid];
 48 }
 49 
 50 il void rebuild(RG int &x){ top=0,dfs(x),x=divide(1,top); return; }
 51 
 52 il int qrank(RG int x,RG int k){
 53     RG int res=1;
 54     while (x){
 55     if (k<=val[x]) x=ch[x][0];
 56     else res+=sz[ch[x][0]]+(!del[x]),x=ch[x][1];
 57     }
 58     return res;
 59 }
 60 
 61 il int find(RG int x,RG int k){
 62     while (x){
 63     if (!del[x] && k==sz[ch[x][0]]+1) return val[x];
 64     if (k<=sz[ch[x][0]]) x=ch[x][0];
 65     else k-=sz[ch[x][0]]+(!del[x]),x=ch[x][1];
 66     }
 67     return val[x];
 68 }
 69 
 70 il int* Insert(RG int &x,RG int k){
 71     if (!x){ val[x=++tot]=k,sz[x]=cover[x]=1; return NULL; }
 72     sz[x]++,cover[x]++; int *p=Insert(ch[x][val[x]<=k],k);
 73     if (max(cover[ch[x][0]],cover[ch[x][1]])>cover[x]*alpha) p=&x;
 74     return p;
 75 }
 76 
 77 il void insert(RG int k){ int *x=Insert(rt,k); if (x) rebuild(*x); return; }
 78 
 79 il void Erase(RG int x,RG int k){
 80     while (x){
 81     sz[x]--; if (!del[x] && k==sz[ch[x][0]]+1){ del[x]=1; return; }
 82     if (k<=sz[ch[x][0]]) x=ch[x][0]; else k-=sz[ch[x][0]]+(!del[x]),x=ch[x][1];
 83     }
 84     return;
 85 }
 86 
 87 il void erase(RG int k){ Erase(rt,qrank(rt,k)); if (sz[rt]<cover[rt]*alpha) rebuild(rt); return; }
 88 
 89 il void work(){
 90     Q=gi(); RG int type,x;
 91     while (Q--){
 92     type=gi(),x=gi();
 93     if (type==1) insert(x);
 94     if (type==2) erase(x);
 95     if (type==3) printf("%d\n",qrank(rt,x));
 96     if (type==4) printf("%d\n",find(rt,x));
 97     if (type==5) printf("%d\n",find(rt,qrank(rt,x)-1));
 98     if (type==6) printf("%d\n",find(rt,qrank(rt,x+1)));
 99     }
100     return;
101 }
102 
103 int main(){
104     File("tree");
105     work();
106     return 0;
107 }

 

最近又学了一下非旋转$treap$:

 1 #include <bits/stdc++.h>
 2 #define il inline
 3 #define RG register
 4 #define ll long long
 5 #define PR pair<int,int>
 6 #define inf (1<<30)
 7 #define N (100010)
 8 
 9 using namespace std;
10 
11 int val[N],key[N],sz[N],ls[N],rs[N],rt,n,tot;
12 
13 il int gi(){
14   RG int x=0,q=1; RG char ch=getchar();
15   while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
16   if (ch=='-') q=-1,ch=getchar();
17   while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar();
18   return q*x;
19 }
20 
21 il void pushup(RG int x){
22   sz[x]=sz[ls[x]]+sz[rs[x]]+1; return;
23 }
24 
25 il int merge(RG int x,RG int y){
26   if (!x || !y) return x|y;
27   if (key[x]<key[y]){
28     rs[x]=merge(rs[x],y),pushup(x); return x;
29   } else{
30     ls[y]=merge(x,ls[y]),pushup(y); return y;
31   }
32 }
33 
34 il PR split(RG int x,RG int k){
35   if (!x) return make_pair(0,0); RG PR P;
36   if (k<=sz[ls[x]]) P=split(ls[x],k),ls[x]=P.second,P.second=x;
37   else P=split(rs[x],k-sz[ls[x]]-1),rs[x]=P.first,P.first=x;
38   pushup(x); return P;
39 }
40 
41 il int rk(RG int x,RG int k){
42   RG int res=0,tmp=inf;
43   while (x){
44     if (k==val[x]) tmp=min(tmp,res+sz[ls[x]]+1);
45     k<=val[x]?x=ls[x]:(res+=sz[ls[x]]+1,x=rs[x]);
46   }
47   return tmp==inf ? res : tmp;
48 }
49 
50 il int find(RG int x,RG int k){
51   if (k==sz[ls[x]]+1) return val[x];
52   if (k<=sz[ls[x]]) return find(ls[x],k);
53   return find(rs[x],k-sz[ls[x]]-1);
54 }
55 
56 il int pre(RG int x,RG int k){
57   if (!x) return -inf;
58   if (k>val[x]) return max(val[x],pre(rs[x],k));
59   return pre(ls[x],k);
60 }
61 
62 il int nxt(RG int x,RG int k){
63   if (!x) return inf;
64   if (k<val[x]) return min(val[x],nxt(ls[x],k));
65   return nxt(rs[x],k);
66 }
67 
68 il void insert(RG int x){
69   sz[++tot]=1,val[tot]=x,key[tot]=rand()<<15|rand();
70   RG int k=rk(rt,x);
71   RG PR P=split(rt,k);
72   rt=merge(merge(P.first,tot),P.second);
73 }
74 
75 il void del(RG int x){
76   RG int k=rk(rt,x);
77   RG PR P1=split(rt,k);
78   RG PR P2=split(P1.first,k-1);
79   rt=merge(P2.first,P1.second);
80 }
81 
82 int main(){
83 #ifndef ONLINE_JUDGE
84   freopen("treap.in","r",stdin);
85   freopen("treap.out","w",stdout);
86 #endif
87   srand(19260817); n=gi();
88   for (RG int i=1,op,x;i<=n;++i){
89     op=gi(),x=gi();
90     if (op==1) insert(x); if (op==2) del(x);
91     if (op==3) printf("%d\n",rk(rt,x));
92     if (op==4) printf("%d\n",find(rt,x));
93     if (op==5) printf("%d\n",pre(rt,x));
94     if (op==6) printf("%d\n",nxt(rt,x));
95   }
96   return 0;
97 }

 

posted @ 2017-03-03 22:55  wfj_2048  阅读(210)  评论(0编辑  收藏  举报