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 }