## 【BZOJ3224】普通平衡树（splay）

1. 插入x数
2. 删除x数(若有多个相同的数，因只删除一个)
3. 查询x数的排名(若有多个相同的数，因输出最小的排名)
4. 查询排名为x的数
5. 求x的前驱(前驱定义为小于x，且最大的数)
6. 求x的后继(后继定义为大于x，且最小的数)

1.n的数据范围：n<=100000
2.每个数的数据范围：[-1e7,1e7]

  1 var t:array[0..300000,0..1]of longint;
2     sum,b,fa,num:array[0..300000]of longint;
3     n,i,x,y,root,cnt,save,tmp,m:longint;
4     flag:boolean;
5
6
7 procedure pushup(x:longint);
8 var l,r:longint;
9 begin
10  l:=t[x,0]; r:=t[x,1];
11  sum[x]:=sum[l]+sum[r]+1;
12 end;
13
14 procedure rotate(x:longint;var k:longint);
15 var y,z,l,r:longint;
16 begin
17  y:=fa[x]; z:=fa[y];
18  if t[y,0]=x then l:=0
19   else l:=1;
20  r:=l xor 1;
21  if y<>k then
22  begin
23   if t[z,0]=y then t[z,0]:=x
24    else t[z,1]:=x;
25  end
26   else k:=x;
27  fa[t[x,r]]:=y; fa[x]:=z; fa[y]:=x;
28  t[y,l]:=t[x,r]; t[x,r]:=y;
29  pushup(y);
30  pushup(x);
31 end;
32
33 procedure splay(x:longint;var k:longint);
34 var y,z:longint;
35 begin
36  while x<>k do
37  begin
38   y:=fa[x]; z:=fa[y];
39   if y<>k then
40   begin
41    if (t[z,0]=y)xor(t[y,0]=x) then rotate(x,k)
42     else rotate(y,k);
43   end
44    else k:=x;
45   rotate(x,k);
46  end;
47
48 end;
49
50 function pred(x:longint):longint;
51 var k,last:longint;
52 begin
53  k:=root; last:=num[root];
54  while k<>0 do
55  begin
56   if num[k]<x then begin last:=num[k]; k:=t[k,1]; end
57    else k:=t[k,0];
58  end;
59  exit(last);
60 end;
61
62 function succ(x:longint):longint;
63 var k,last:longint;
64 begin
65  k:=root; last:=num[root];
66  while k<>0 do
67  begin
68   if num[k]>x then begin last:=num[k]; k:=t[k,0]; end
69    else k:=t[k,1];
70  end;
71  exit(last);
72 end;
73
74 function rank(x:longint):longint;
75 var k:longint;
76 begin
77  x:=pred(x);
78  k:=root; rank:=0;
79  while k>0 do
80  begin
81   if num[k]<=x then begin rank:=rank+sum[t[k,0]]+1; k:=t[k,1]; end
82    else k:=t[k,0];
83  end;
84  inc(rank);
85 end;
86
87 function kth(x:longint):longint;
88 var tmp,k:longint;
89 begin
90  k:=root;
91  while true do
92  begin
93   tmp:=sum[t[k,0]]+1;
94   if tmp=x then exit(k);
95   if tmp>x then k:=t[k,0]
96    else
97    begin
98     k:=t[k,1]; x:=x-tmp;
99    end;
100  end;
101 end;
102
103 function find(x:longint):longint;
104 var k:longint;
105 begin
106  k:=root;
107  while true do
108  begin
109   if num[k]=x then exit(k)
110    else if num[k]<x then k:=t[k,1]
111     else k:=t[k,0];
112  end;
113 end;
114
115 procedure ins(x:longint);
116 var tmp,l,r,k1:longint;
117 begin
118  tmp:=rank(x);
119  l:=kth(tmp-1);
120  r:=kth(tmp);
121  splay(l,root);
122  splay(r,t[root,1]);
123  k1:=t[root,1];
124  inc(cnt); t[k1,0]:=cnt; fa[cnt]:=k1; sum[cnt]:=1; num[cnt]:=x;
125 // inc(sum[k1]);
126 // inc(sum[root]);
127 end;
128
129 procedure del(x:longint);
130 var k1,k2,l,r:longint;
131 begin
132  tmp:=rank(x);
133  l:=kth(tmp-1);
134  r:=kth(tmp+1);
135  splay(l,root);
136  splay(r,t[root,1]);
137  k1:=t[root,1]; k2:=t[k1,0];
138  sum[k1]:=sum[t[k1,1]]+1; fa[k2]:=0; sum[k2]:=0;
139  t[k1,0]:=0;
140
141  fa[k2]:=0; sum[k2]:=0; t[k2,0]:=0; t[k2,1]:=0;
142
143 end;
144
145 begin
146  assign(input,'bzoj3224.in'); reset(input);
147  assign(output,'bzoj3224.out'); rewrite(output);
149  num[1]:=maxlongint; sum[1]:=3; t[1,0]:=2; t[1,1]:=3;
150  num[2]:=-maxlongint; sum[2]:=1; fa[2]:=1;
151  num[3]:=maxlongint; sum[3]:=1; fa[3]:=1;
152
153  root:=1; cnt:=3;
154  for i:=1 to n do
155  begin
157   case x of
158    1:
159    begin
160     ins(y);
161     inc(m);
162    end;
163    2:
164    begin
165     del(y);
166     dec(m);
167    end;
168
169    3:writeln(rank(y)-1);
170
171    4:writeln(num[kth(y+1)]);
172    5:writeln(pred(y));
173    6:writeln(succ(y));
174   end;
175  end;
176  close(input);
177  close(output);
178 end.

UPD(2018.9.15）：C++

  1 #include<cstdio>
2 #include<cstring>
3 #include<string>
4 #include<cmath>
5 #include<iostream>
6 #include<algorithm>
7 #include<map>
8 #include<set>
9 #include<queue>
10 #include<vector>
11 using namespace std;
12 typedef long long ll;
13 typedef unsigned int uint;
14 typedef unsigned long long ull;
15 typedef pair<int,int> PII;
16 typedef vector<int> VI;
17 #define fi first
18 #define se second
19 #define MP make_pair
20 #define N   500000
21 #define MOD 1000000007
22 #define eps 1e-8
23 #define pi acos(-1)
24 #define oo 2e9
25
26 int t[N][2],size[N],fa[N],num[N],root,cnt;
27
29 {
30    int v=0,f=1;
31    char c=getchar();
32    while(c<48||57<c) {if(c=='-') f=-1; c=getchar();}
33    while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
34    return v*f;
35 }
36
37 void pushup(int x)
38 {
39     size[x]=size[t[x][0]]+size[t[x][1]]+1;
40 }
41
42 void rotate(int x,int &k)
43 {
44     int y=fa[x];
45     int z=fa[y];
46     int l;
47     if(t[y][0]==x) l=0;
48      else l=1;
49     int r=l^1;
50     if(y!=k)
51     {
52         if(t[z][0]==y) t[z][0]=x;
53          else t[z][1]=x;
54     }
55      else k=x;
56     fa[t[x][r]]=y; fa[x]=z; fa[y]=x;
57     t[y][l]=t[x][r]; t[x][r]=y;
58     pushup(y);
59     pushup(x);
60 }
61
62 void splay(int x,int &k)
63 {
64     while(x!=k)
65     {
66         int y=fa[x];
67         int z=fa[y];
68         if(y!=k)
69         {
70             if((t[z][0]==y)^(t[y][0]==x)) rotate(x,k);
71              else rotate(y,k);
72         }
73          else k=x;
74         rotate(x,k);
75     }
76 }
77
78 int pred(int x)
79 {
80     int k=root;
81     int last=num[root];
82     while(k)
83     {
84         if(num[k]<x){last=num[k]; k=t[k][1];}
85          else k=t[k][0];
86     }
87     return last;
88 }
89
90 int succ(int x)
91 {
92     int k=root;
93     int last=num[root];
94     while(k)
95     {
96         if(num[k]>x){last=num[k]; k=t[k][0];}
97          else k=t[k][1];
98     }
99     return last;
100 }
101
102 int rank(int x)
103 {
104     x=pred(x);
105     int k=root;
106     int s=0;
107     while(k)
108     {
109         if(num[k]<=x){s+=size[t[k][0]]+1; k=t[k][1];}
110          else k=t[k][0];
111     }
112     s++;
113     return s;
114 }
115
116 int kth(int x)
117 {
118     int k=root;
119     while(1)
120     {
121         int tmp=size[t[k][0]]+1;
122         if(tmp==x) return k;
123         if(tmp>x) k=t[k][0];
124          else{k=t[k][1]; x-=tmp;}
125     }
126 }
127
128 void Insert(int x)
129 {
130     int tmp=rank(x);
131     int l=kth(tmp-1);
132     int r=kth(tmp);
133     splay(l,root);
134     splay(r,t[root][1]);
135     int k=t[root][1];
136     t[k][0]=++cnt; fa[cnt]=k; size[cnt]=1; num[cnt]=x;
137 }
138
139 void Delete(int x)
140 {
141     int tmp=rank(x);
142     int l=kth(tmp-1);
143     int r=kth(tmp+1);
144     splay(l,root);
145     splay(r,t[root][1]);
146      int k1=t[root][1];
147      int k2=t[k1][0];
148      size[k1]=size[t[k1][1]]+1; t[k1][0]=0;
149      fa[k2]=0; size[k2]=0;
150     t[k2][0]=0; t[k2][1]=0;
151 }
152
153 int main()
154 {
155     //freopen("bzoj3224.in","r",stdin);
156     //freopen("bzoj3224.out","w",stdout);
157     int n;
158     scanf("%d",&n);
159     num[1]=-oo; size[1]=2; t[1][1]=2;
160     num[2]=oo; size[2]=1; fa[2]=1;
161     root=1; cnt=2;
162     for(int i=1;i<=n;i++)
163     {
164         int x,y,ans;
165         scanf("%d%d",&x,&y);
166         if(x==1) Insert(y);
167         if(x==2) Delete(y);
168         if(x==3)
169         {
170             ans=rank(y)-1;
171             printf("%d\n",ans);
172         }
173         if(x==4)
174         {
175             ans=num[kth(y+1)];
176             printf("%d\n",ans);
177         }
178         if(x==5)
179         {
180             ans=pred(y);
181             printf("%d\n",ans);
182         }
183         if(x==6)
184         {
185             ans=succ(y);
186             printf("%d\n",ans);
187         }
188     }
189 }

posted on 2017-01-17 07:51  myx12345  阅读(280)  评论(0编辑  收藏  举报