bzoj 3224 Tyvj 1728 普通平衡树

平衡树。

插入,删除,前驱,后继,实现名次树。

splay实现。

“查询值为x的数的排名,有多个相同的数输出最小名次”查询比x小的数的个数加一就行了。

  1 #include<iostream>
  2 #include<cstring>
  3 #include<cstdio>
  4 #include<algorithm>
  5 using namespace std;
  6 const int dian=100005;
  7 int siz[dian],fa[dian],ch[dian][3],ky[dian];
  8 int n,a,flag,cnt,root;
  9 void pushup(int x){
 10     siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1;
 11 }
 12 void rotate(int x){
 13     int y=fa[fa[x]];
 14     int ok=(ch[fa[x]][0]==x);
 15     ch[fa[x]][ok^1]=ch[x][ok];
 16     fa[ch[x][ok]]=fa[x];
 17     ch[x][ok]=fa[x];
 18     fa[fa[x]]=x;
 19     fa[x]=y;
 20     if(y!=-1){
 21         if(ch[y][0]==ch[x][ok])
 22             ch[y][0]=x;
 23         else
 24             ch[y][1]=x;
 25     }
 26     pushup(ch[x][ok]);
 27     pushup(x);
 28 }
 29 void splay(int x){
 30     for(int y;(y=fa[x])!=-1;rotate(x)){
 31         if(fa[y]!=-1){
 32             if((ch[fa[y]][0]==y&&ch[y][0]==x)||(ch[fa[y]][1]==y&&ch[y][1]==x))
 33                 rotate(y);
 34             else
 35                 rotate(x);
 36         }
 37     }
 38     root=x;
 39 }
 40 void insert(int x){
 41     if(root==-1){
 42         root=++cnt;
 43         ch[root][0]=-1;
 44         ch[root][1]=-1;
 45         ky[root]=x;
 46         siz[root]++;
 47         fa[root]=-1;
 48     }
 49     else{
 50         int k=root;
 51         siz[k]++;
 52         while(ch[k][ky[k]<x]!=-1){
 53             k=ch[k][ky[k]<x];
 54             siz[k]++;
 55         }
 56         ch[k][ky[k]<x]=++cnt;
 57         ky[cnt]=x;
 58         ch[cnt][0]=-1;
 59         ch[cnt][1]=-1;
 60         siz[cnt]++;
 61         fa[cnt]=k;
 62         splay(cnt);
 63     }
 64 }
 65 int find(int x){
 66     int cur=root;
 67     while(ky[cur]!=x){
 68         if(ky[cur]<x)
 69             cur=ch[cur][1];
 70         else
 71             cur=ch[cur][0];
 72     }
 73     return cur;
 74 }
 75 void del(int x){
 76     splay(x);
 77     if(ch[x][0]==-1){
 78         fa[ch[x][1]]=-1;
 79         root=ch[x][1];
 80     }
 81     else if(ch[x][1]==-1){
 82         fa[ch[x][0]]=-1;
 83         root=ch[x][0];
 84     }
 85     else{
 86         fa[ch[x][0]]=-1;
 87         int tmp=ch[x][0];
 88         while(ch[tmp][1]!=-1)
 89             tmp=ch[tmp][1];
 90         splay(tmp);
 91         ch[tmp][1]=ch[x][1];
 92         fa[ch[x][1]]=tmp;
 93         pushup(tmp);
 94     }
 95 }
 96 int rank(int k,int x){
 97     if(k==-1)
 98         return 0;
 99     if(ky[k]<x)
100         return siz[ch[k][0]]+1+rank(ch[k][1],x);
101     else
102         return rank(ch[k][0],x);
103 }
104 int rak(int k,int x){
105     if(siz[ch[k][0]]>=x)
106         return rak(ch[k][0],x);
107     if(siz[ch[k][0]]+1==x)
108         return ky[k];
109     return rak(ch[k][1],x-1-siz[ch[k][0]]);
110 }
111 int pred(int x){
112     int llans=0xcfcfcfcf;
113     int cur=root;
114     while(cur!=-1){
115         if(ky[cur]<x){
116             if(llans<ky[cur])
117                 llans=ky[cur];
118             cur=ch[cur][1];
119         }
120         else
121             cur=ch[cur][0];
122     }
123     return llans;
124 }
125 int nxtd(int x){
126     int llans=0x3f3f3f3f;
127     int cur=root;
128     while(cur!=-1){
129         if(ky[cur]>x){
130             if(llans>ky[cur])
131                 llans=ky[cur];
132             cur=ch[cur][0];
133         }
134         else
135             cur=ch[cur][1];
136     }
137     return llans;
138 }
139 int main(){
140     memset(siz,0,sizeof(siz));
141     cnt=0;
142     root=-1;
143     scanf("%d",&n);
144     for(int i=1;i<=n;i++){
145         scanf("%d%d",&flag,&a);
146         if(flag==1)
147             insert(a);
148         else if(flag==2)
149             del(find(a));
150         else if(flag==3)
151             printf("%d\n",rank(root,a)+1);
152         else if(flag==4)
153             printf("%d\n",rak(root,a));
154         else if(flag==5)
155             printf("%d\n",pred(a));
156         else
157             printf("%d\n",nxtd(a));
158     }
159     return 0;
160 }

 

posted @ 2016-12-09 19:16  dugudashen  阅读(217)  评论(0编辑  收藏  举报