• 【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
    ",ans);
    172         }
    173         if(x==4)
    174         {
    175             ans=num[kth(y+1)];
    176             printf("%d
    ",ans);
    177         }
    178         if(x==5)
    179         {
    180             ans=pred(y);
    181             printf("%d
    ",ans);
    182         }
    183         if(x==6)
    184         {
    185             ans=succ(y);
    186             printf("%d
    ",ans);
    187         }    
    188     }
    189 }
  • 相关阅读:
    Linux 安装 PostgreSQL
    【Linux】ZeroMQ 在 centos下的安装
    Celery
    Django学习之完成数据库主从复制、读写分离和一主多从情况下的使用办法
    python异步编程之asyncio(百万并发)
    Python正则表达式中的re.S,re.M,re.I的作用
    云开发 :云原生(Cloud Native)
    极简Unity调用Android方法
    UnityShader快速上手指南(四)
    UnityShader快速上手指南(三)
  • 原文地址:https://www.cnblogs.com/myx12345/p/6291641.html
Copyright © 2020-2023  润新知