替罪羊树模板(题目:普通平衡树)
Posted scx2015noip-as-php
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了替罪羊树模板(题目:普通平衡树)相关的知识,希望对你有一定的参考价值。
我要喷写这题题解的人,害得我调错了 $n$ 多个小时!!
1 #include<bits/stdc++.h> 2 #define lc tr[o].l 3 #define rc tr[o].r 4 #define N 100001 5 #define inf 2147483647 6 const double alpha=0.7; 7 using namespace std; 8 inline int read(){ 9 int x=0; bool f=1; char c=getchar(); 10 while(!isdigit(c)){if(c==‘-‘) f=0; c=getchar();} 11 while(isdigit(c)){x=(x<<3)+(x<<1)+c-‘0‘; c=getchar();} 12 if(!f) return 0-x; 13 return x; 14 } 15 int n,root,op,x,cnt; 16 int v[N]; 17 int bad,fa; 18 bool exist,son; 19 namespace ForceTree{ 20 struct node{ 21 int l,r,val,siz,cnt; 22 bool deleted; 23 }tr[N<<2]; 24 vector<int>v; 25 inline bool isbad(int o){ 26 //cout<<tr[lc].cnt<<‘ ‘<<tr[rc].cnt<<‘ ‘<<alpha*tr[o].cnt+5<<‘ ‘<<(tr[lc].cnt>alpha*tr[o].cnt+5)<<‘ ‘<<(tr[rc].cnt>alpha*tr[o].cnt+5)<<‘ ‘; 27 return tr[lc].cnt>alpha*tr[o].cnt+5 || tr[rc].cnt>alpha*tr[o].cnt+5; 28 } 29 inline void pushup(int o){ 30 tr[o].siz = (!tr[o].deleted && tr[o].val!=inf && tr[o].val!=-inf)+tr[lc].siz+tr[rc].siz; 31 tr[o].cnt = 1+tr[lc].cnt+tr[rc].cnt; 32 } 33 void dfs(int o){ 34 if(lc) dfs(lc); 35 if(!tr[o].deleted) v.push_back(o); 36 if(rc) dfs(rc); 37 } 38 void build(int &o,int l,int r){ 39 if(l>=r){o=0; return;} //o=0,注意!不然某个叶子结点的儿子可能没刷掉! 40 int mid=(l+r)>>1; 41 o=v[mid]; 42 //printf("build:%d %d %d %d ",o,tr[o].val,l,r); 43 build(lc,l,mid), build(rc,mid+1,r); 44 pushup(o); 45 } 46 void rebuild(int &o){ 47 //printf("rebuild "); 48 v.clear(); 49 dfs(o); 50 build(o,0,v.size()); 51 } 52 void insert(int &o,int x){ 53 if(!o){ 54 o=++cnt; 55 lc=rc=0; 56 tr[o].deleted=0; 57 if(x==-inf || x==inf) tr[o].siz=0; 58 else tr[o].siz=1; 59 tr[o].cnt=1; 60 tr[o].val=x; 61 return; 62 } 63 else{ 64 if(x!=-inf && x!=inf) ++tr[o].siz; 65 ++tr[o].cnt; 66 if(x<tr[o].val){ 67 insert(lc,x); 68 if(bad==lc) fa=o, son=0; //bad点的父亲到后面要更新儿子 69 } 70 else{ 71 insert(rc,x); 72 if(bad==rc) fa=o, son=1; 73 } 74 if(isbad(o)) bad=o; //优化? 75 } 76 } 77 int rank(int o,int x){ 78 int ans=1; 79 while(o){ 80 //printf("%d %d %d ",tr[o].val,tr[o].siz,tr[lc].siz); 81 if(x<=tr[o].val){ 82 if(x==tr[o].val) exist=1; 83 o=lc; 84 } 85 else{ 86 //printf("%d %d ",tr[lc].siz,(tr[o].val!=-inf && tr[o].val!=inf && !tr[o].deleted)); 87 ans+=tr[lc].siz+(tr[o].val!=-inf && tr[o].val!=inf && !tr[o].deleted); 88 o=rc; 89 } 90 } 91 return ans; 92 } 93 int kth(int o,int x){ 94 //printf("rank:%d ",x); 95 if(x<=0) return -inf; 96 while(o){ 97 //printf("%d %d ",tr[o].val,tr[lc].siz); 98 if(!tr[o].deleted && tr[o].val!=inf && tr[o].val!=-inf && tr[lc].siz+1==x) return tr[o].val; 99 if(x<=tr[lc].siz) o=lc; 100 else{ 101 x-=tr[lc].siz+(tr[o].val!=-inf && tr[o].val!=inf && !tr[o].deleted); 102 o=rc; 103 } 104 } 105 return inf; 106 } 107 void erase(int o,int rk){ 108 if(!exist) return; 109 while(o){ 110 if(!tr[o].deleted && tr[o].val!=inf && tr[o].val!=-inf && tr[lc].siz+1==rk){ 111 //printf("erase:%d %d ",tr[o].val,x); 112 if(tr[o].val==x) tr[o].deleted=1, --tr[o].siz; 113 return; 114 } 115 --tr[o].siz; 116 if(rk<=tr[lc].siz) o=lc; 117 else{ 118 rk-=tr[lc].siz+(tr[o].val!=-inf && tr[o].val!=inf && !tr[o].deleted); 119 o=rc; 120 } 121 } 122 } 123 }; 124 using namespace ForceTree; 125 int main(){ 126 //freopen("rand.in","r",stdin); 127 //freopen("count.out","w",stdout); 128 n=read(); 129 insert(root,-2147483647), insert(root,2147483647); 130 while(n--){ 131 op=read(),x=read(); 132 if(op==1){ 133 bad=-1; 134 insert(root,x); 135 if(bad!=-1){ 136 //printf("bad:%d %d %d %d ",root,fa,bad,tr[bad].val); 137 if(bad==root) rebuild(bad), root=bad; //注意!! 138 else{ 139 rebuild(bad); 140 if(!son) tr[fa].l=bad; 141 else tr[fa].r=bad; 142 } 143 } 144 } 145 if(op==2){ 146 exist=0; 147 erase(root,rank(root,x)); 148 } 149 if(op==3) printf("%d ",rank(root,x)); 150 if(op==4) printf("%d ",kth(root,x)); 151 if(op==5) printf("%d ",kth(root,rank(root,x)-1)); 152 if(op==6) printf("%d ",kth(root,rank(root,x+1))); 153 } 154 return 0; 155 } 156 /* 157 3 158 1 87 159 1 68 160 3 50 161 162 45 163 1 914241 164 1 639471 165 5 917713 166 6 912745 167 1 234811 168 1 297728 169 3 297728 170 1 6927 171 5 645391 172 1 664569 173 2 914241 174 1 134689 175 1 868271 176 1 842266 177 5 850426 178 1 286545 179 4 1 180 1 333833 181 1 274177 182 1 568845 183 1 157569 184 4 13 185 1 732493 186 4 7 187 4 9 188 5 646117 189 1 136381 190 1 473089 191 1 419305 192 1 639776 193 3 473089 194 4 7 195 6 234571 196 1 37685 197 1 321207 198 1 496713 199 1 531105 200 2 234811 201 2 157569 202 1 326601 203 1 317437 204 1 791873 205 1 931097 206 1 224521 207 3 317437 208 209 50 210 1 1 211 1 2 212 1 3 213 1 4 214 1 5 215 1 6 216 1 7 217 1 8 218 1 9 219 1 10 220 1 11 221 1 12 222 1 13 223 1 14 224 1 15 225 1 16 226 1 17 227 1 18 228 1 19 229 1 20 230 1 21 231 1 22 232 1 23 233 1 24 234 235 5 236 1 1 237 1 5 238 2 5 239 3 4 240 */
以上是关于替罪羊树模板(题目:普通平衡树)的主要内容,如果未能解决你的问题,请参考以下文章