TYVJ 1730 二逼平衡树 线段树套平衡树
没什么好说的。。被坑了。。
查询排名为k的数时,二分这个数,转化成查找w的排名。
若w这个数不存在,就先插入w,然后把w旋转到根,既可以求w的排名。
View Code
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <cstdlib> 5 #include <algorithm> 6 7 #define INF 100000000 8 #define N 1110000 9 #define BUG system("pause") 10 11 using namespace std; 12 13 int sz[N],fa[N],son[N][2],val[N],root[N]; 14 int n,cnt,m; 15 int a[N],b[N]; 16 int opt,sq,sum,suc,pre,pos; 17 int q[N],tot; 18 19 struct ST 20 { 21 int l,r; 22 }T[N<<2]; 23 24 inline void prt(int x) 25 { 26 if(!x) return; 27 prt(son[x][0]); 28 printf("%d ",val[x]); 29 prt(son[x][1]); 30 } 31 32 inline void pushup(int x) 33 { 34 if(!x) return; 35 sz[x]=sz[son[x][0]]+sz[son[x][1]]+1; 36 } 37 38 inline void link(int x,int y,int c) 39 { 40 fa[x]=y; son[y][c]=x; 41 } 42 43 void rotate(int x,int c) 44 { 45 int y=fa[x]; 46 link(x,fa[y],son[fa[y]][1]==y); 47 link(son[x][!c],y,c); 48 link(y,x,!c); 49 pushup(y); 50 } 51 52 void splay(int x,int g,int &rt) 53 { 54 while(fa[x]!=g) 55 { 56 int y=fa[x]; 57 int cy=(son[fa[y]][1]==y),cx=(son[y][1]==x); 58 if(fa[y]==g) rotate(x,cx); 59 else 60 { 61 if(cx==cy) rotate(y,cy); 62 else rotate(x,cx); 63 rotate(x,cy); 64 } 65 } 66 pushup(x); 67 if(!g) rt=x; 68 } 69 70 inline int getnum() 71 { 72 if(tot) return q[tot--]; 73 return ++cnt; 74 } 75 76 inline void newnode(int y,int &x,int sp) 77 { 78 x=getnum(); 79 fa[x]=y; val[x]=sp; sz[x]=1; 80 son[x][1]=son[x][0]=0; 81 } 82 83 inline void pack(int &u,int l,int r,int f) 84 { 85 if(r<l) return; 86 int mid=(l+r)>>1; 87 newnode(f,u,a[mid]); 88 pack(son[u][0],l,mid-1,u); 89 pack(son[u][1],mid+1,r,u); 90 pushup(u); 91 } 92 93 inline void bsplay(int u,int l,int r) 94 { 95 newnode(0,root[u],-INF); 96 newnode(root[u],son[root[u]][1],INF); 97 sz[root[u]]=2; 98 pack(son[son[root[u]][1]][0],l,r,son[root[u]][1]); 99 pushup(son[son[root[u]][1]][0]); pushup(son[root[u]][1]); 100 } 101 102 inline void build(int u,int l,int r) 103 { 104 T[u].l=l; T[u].r=r; 105 if(l==r) 106 { 107 bsplay(u,l,r); 108 return; 109 } 110 int mid=(l+r)>>1; 111 build(u<<1,l,mid); 112 build(u<<1|1,mid+1,r); 113 sort(a+l,a+r+1); 114 bsplay(u,l,r); 115 } 116 117 inline void read() 118 { 119 scanf("%d%d",&n,&m); 120 for(int i=1;i<=n;i++) scanf("%d",&a[i]),b[i]=a[i]; 121 build(1,1,n); 122 } 123 124 inline int find(int sp,int x) 125 { 126 while(x) 127 { 128 if(val[x]==sp) return x; 129 x=son[x][val[x]<sp]; 130 } 131 } 132 133 inline int getmin(int x) 134 { 135 while(son[x][0]) x=son[x][0]; 136 return x; 137 } 138 139 inline int getmax(int x) 140 { 141 while(son[x][1]) x=son[x][1]; 142 return x; 143 } 144 145 inline void insert(int sp,int &rt) 146 { 147 int x=rt; 148 while(son[x][val[x]<sp]) x=son[x][val[x]<sp]; 149 newnode(x,son[x][val[x]<sp],sp); 150 splay(son[x][val[x]<sp],0,rt); 151 } 152 153 inline void del(int sp,int &rt) 154 { 155 int x=find(sp,rt); 156 splay(x,0,rt); 157 int y=getmax(son[x][0]),z=getmin(son[x][1]); 158 splay(y,0,rt); splay(z,y,rt); 159 q[++tot]=son[z][0]; son[z][0]=0; 160 pushup(z); pushup(y); 161 } 162 163 inline int pred(int x,int sp) 164 { 165 int re=-INF; 166 while(x) 167 { 168 if(val[x]<sp) re=max(val[x],re); 169 x=son[x][val[x]<sp]; 170 } 171 return re; 172 } 173 174 inline int succ(int x,int sp) 175 { 176 int re=INF; 177 while(x) 178 { 179 if(val[x]>sp) re=min(val[x],re); 180 x=son[x][val[x]<=sp];//!!!!! 181 } 182 return re; 183 } 184 185 inline void query(int u,int l,int r) 186 { 187 if(T[u].l>=l&&T[u].r<=r) 188 { 189 if(opt==1) 190 { 191 insert(sq,root[u]); 192 sum+=sz[son[root[u]][0]]-1; 193 del(sq,root[u]); 194 } 195 else if(opt==3) 196 { 197 del(b[pos],root[u]); 198 insert(sq,root[u]); 199 } 200 else if(opt==4) 201 { 202 pre=max(pre,pred(root[u],sq)); 203 } 204 else 205 { 206 suc=min(suc,succ(root[u],sq)); 207 } 208 return; 209 } 210 int mid=(T[u].l+T[u].r)>>1; 211 if(r<=mid) query(u<<1,l,r); 212 else if(l>mid) query(u<<1|1,l,r); 213 else query(u<<1,l,mid),query(u<<1|1,mid+1,r); 214 if(opt==3) 215 { 216 del(b[pos],root[u]); 217 insert(sq,root[u]); 218 } 219 } 220 221 inline void go() 222 { 223 for(int i=1,aa,bb,k;i<=m;i++) 224 { 225 scanf("%d",&opt); 226 if(opt==1) 227 { 228 scanf("%d%d%d",&aa,&bb,&sq); 229 sum=0; 230 query(1,aa,bb); 231 printf("%d\n",sum+1); 232 } 233 else if(opt==2) 234 { 235 scanf("%d%d%d",&aa,&bb,&k); 236 opt=1; 237 int l=0,r=INF,ans; 238 while(l<=r) 239 { 240 int mid=(l+r)>>1; 241 sum=0; 242 sq=mid; query(1,aa,bb); 243 if(sum+1<=k) ans=mid,l=mid+1; 244 else r=mid-1; 245 } 246 printf("%d\n",ans); 247 } 248 else if(opt==3) 249 { 250 scanf("%d%d",&pos,&sq); 251 query(1,pos,pos); 252 b[pos]=sq; 253 } 254 else if(opt==4) 255 { 256 scanf("%d%d%d",&aa,&bb,&sq); 257 pre=-INF; 258 query(1,aa,bb); 259 printf("%d\n",pre); 260 } 261 else 262 { 263 scanf("%d%d%d",&aa,&bb,&sq); 264 suc=INF; 265 query(1,aa,bb); 266 printf("%d\n",suc); 267 } 268 } 269 } 270 271 int main() 272 { 273 read(),go(); 274 return 0; 275 }
没有人能阻止我前进的步伐,除了我自己!