【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 }
null