BZOJ3224 Tyvj 1728 普通平衡树
splay,各种初级操作。
一个麻烦的地方就是可以有重复数字,可以用想办法标记下来,如果用数组的话需要开的空间太大,可以用map标记,虽然慢了点。
还是第一次写着个东西,有一个地方写了很多次每次都错,就是insert的时候,最后把刚加进来的节点伸展到根节点,应该是spaly(tot,0);每次都写成splay(x,0)..
1 #include <cstdio> 2 #include <algorithm> 3 #include <map> 4 using namespace std; 5 const int maxn = 100005; 6 int fa[maxn],son[2][maxn],val[maxn],siz[maxn]; 7 int root,tot,cnt; 8 map<int,int>mp; 9 void rota(int w,int x){ 10 int y = fa[x]; 11 son[!w][y] = son[w][x]; 12 if(son[w][x])fa[son[w][x]] = y; 13 fa[x] = fa[y]; 14 if(fa[y])son[y==son[1][fa[y]]][fa[y]] = x; 15 fa[y] = x; 16 son[w][x] = y; 17 siz[y] = siz[y]-siz[x]+siz[son[!w][y]]; 18 siz[x] = siz[x]+siz[y]-siz[son[!w][y]]; 19 } 20 void splay(int x,int y){ 21 while(fa[x]!=y){ 22 if(fa[fa[x]]==y)rota(x==son[0][fa[x]],x); 23 else { 24 int w = fa[x]==son[0][fa[fa[x]]]; 25 if(x==son[w][x]){ 26 rota(!w,x); 27 rota(w,x); 28 } 29 else { 30 rota(w,fa[x]); 31 rota(w,x); 32 } 33 } 34 } 35 if(y==0)root = x; 36 } 37 void Ins(int v){ 38 int x = root; 39 while(1){ 40 siz[x]++; 41 if(v==val[x]){splay(x,0);return;} 42 if(v<val[x]){ 43 if(son[0][x])x = son[0][x]; 44 else break; 45 } 46 else { 47 if(son[1][x])x = son[1][x]; 48 else break; 49 } 50 } 51 fa[++tot] = x; 52 val[tot] = v; 53 siz[tot] = 1; 54 if(v<val[x])son[0][x] = tot; 55 else son[1][x] = tot; 56 splay(tot,0);///duoshou 57 } 58 int Find(int v){ 59 int x = root; 60 while(x!=0){ 61 if(v==val[x])break; 62 if(v<val[x])x = son[0][x]; 63 else x = son[1][x]; 64 } 65 splay(x,0); 66 return x; 67 } 68 void Del(int v){ 69 int x = Find(v),y = son[0][x],z = son[1][x]; 70 while(son[1][y])y = son[1][y]; 71 while(son[0][z])z = son[0][z]; 72 73 if(y==0&&z==0){ 74 siz[x]--; 75 if(!siz[x])root = 0; 76 return; 77 } 78 if(y)splay(y,0); 79 if(z)splay(z,y); 80 if(y==0){ 81 siz[x]--;siz[z]--; 82 if(!siz[x])son[0][z] = 0; 83 return; 84 } 85 if(z==0){ 86 siz[x]--;siz[y]--; 87 if(!siz[x])son[1][y] = 0; 88 return; 89 } 90 siz[x]--;siz[y]--;siz[z]--; 91 if(!siz[x])son[0][z] = 0; 92 } 93 int getRank(int v){ 94 int x = Find(v); 95 return siz[son[0][x]]+1; 96 } 97 int getV(int k){ 98 int x = root; 99 while(!(k>siz[son[0][x]]&&k<=siz[son[0][x]]+mp[val[x]])){ 100 if(k<=siz[son[0][x]])x = son[0][x]; 101 else { 102 k-=(siz[son[0][x]]+mp[val[x]]); 103 x = son[1][x]; 104 } 105 } 106 return val[x]; 107 } 108 int getPre(int v){ 109 int x = son[0][Find(v)]; 110 while(son[1][x])x = son[1][x]; 111 return val[x]; 112 } 113 int getNext(int v){ 114 int x = son[1][Find(v)]; 115 while(son[0][x])x = son[0][x]; 116 return val[x]; 117 } 118 int main() 119 { 120 //freopen("in.txt","r",stdin); 121 int n,ans;scanf("%d",&n); 122 for(int i = 1;i<=n;++i){ 123 int op,x;scanf("%d%d",&op,&x); 124 if(op==1){ 125 if(cnt==0){ 126 root = ++tot; 127 siz[tot] = 1; 128 val[tot] = x; 129 } 130 else Ins(x); 131 mp[x]++;cnt++; 132 } 133 else if(op==2){ 134 if(mp[x]){Del(x);mp[x]--;cnt--;} 135 } 136 else if(op==3){ 137 printf("%d\n",getRank(x)); 138 } 139 else if(op==4){ 140 printf("%d\n",getV(x)); 141 } 142 else if(op==5){ 143 if(mp[x])ans = getPre(x); 144 else { 145 Ins(x); 146 ans = getPre(x); 147 Del(x); 148 } 149 printf("%d\n",ans); 150 } 151 else { 152 if(mp[x])ans = getNext(x); 153 else { 154 Ins(x); 155 ans = getNext(x); 156 Del(x); 157 } 158 printf("%d\n",ans); 159 } 160 } 161 return 0; 162 }
弱者究竟为何而战?!