【BZOJ3224】普通平衡树(splay)

题意:

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

1.n的数据范围:n<=100000
2.每个数的数据范围:[-1e7,1e7]
 
思路:为了学LCT才去学的splay
看来又入新坑了
插入的时候把x的前一个(注意不是前驱)转到根,后一个(不是后继)转到根的右儿子,
这样根结点右儿子的左儿子就是要插入的x,直接插入
删除时候类似,这样可以保证每次只删去一个数
  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);
148  readln(n);
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
156   readln(x,y);
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 
 28 int read()
 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  阅读(279)  评论(0编辑  收藏  举报

导航