CRB and Queries
Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 3233 Accepted Submission(s): 148
Problem Description
There are N boys in CodeLand.
Boy i has his coding skill Ai.
CRB wants to know who has the suitable coding skill.
So you should treat the following two types of queries.
Query 1: 1 l v
The coding skill of Boy l has changed to v.
Query 2: 2 l r k
This is a report query which asks the k-th smallest value of coding skill between Boy l and Boy r(both inclusive).
Input
There are multiple test cases.
The first line contains a single integer N.
Next line contains N space separated integers A1, A2, …, AN, where Ai denotes initial coding skill of Boy i.
Next line contains a single integer Q representing the number of queries.
Next Q lines contain queries which can be any of the two types.
1 ≤ N, Q ≤ 105
1 ≤ Ai, v ≤ 109
1 ≤ l ≤ r ≤ N
1 ≤ k ≤ r – l + 1
Output
For each query of type 2, output a single integer corresponding to the answer in a single line.
Sample Input
5
1 2 3 4 5
3
2 2 4 2
1 3 6
2 2 4 2
Sample Output
3
4
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cmath> 5 #include <cstring> 6 7 using namespace std; 8 9 struct treap_node 10 { 11 treap_node *left,*right; 12 int v,fix,size,weight; 13 inline int lsize() {return left ?left ->size:0;} 14 inline int rsize() {return right?right->size:0;} 15 }; 16 17 struct sgt_node 18 { 19 sgt_node *left,*right; 20 int a,b; 21 treap_node *treap; 22 }; 23 24 const int MAXN=100000,MAXM=100000,INF=0x7FFFFFFF/2; 25 const int MAXTN=(MAXN+MAXM)*16,MAXSN=MAXN*2; 26 treap_node TS[MAXTN]; 27 sgt_node SS[MAXSN]; 28 int D,N,M,TC,SC,Tcnt; 29 sgt_node *sgt_root; 30 treap_node *T[MAXN]; 31 32 inline treap_node* new_treap_node(int v) 33 { 34 TS[++TC].v=v; 35 TS[TC].left=TS[TC].right=0; 36 TS[TC].size=TS[TC].weight=1; 37 TS[TC].fix=rand(); 38 return &TS[TC]; 39 } 40 41 inline void treap_rotate_right(treap_node *&p) 42 { 43 treap_node *q=p->left; 44 p->left=q->right; 45 q->right=p; 46 p=q; 47 q=p->right; 48 q->size=q->lsize() + q->rsize() +q->weight; 49 p->size=p->lsize() + p->rsize() +p->weight; 50 } 51 52 inline void treap_rotate_left(treap_node *&p) 53 { 54 treap_node *q=p->right; 55 p->right=q->left; 56 q->left=p; 57 p=q; 58 q=p->left; 59 q->size=q->lsize() + q->rsize() +q->weight; 60 p->size=p->lsize() + p->rsize() +p->weight; 61 } 62 63 int treap_find(treap_node *p,int v) 64 { 65 if (!p) 66 return 0; 67 else if (v<p->v) 68 return treap_find(p->left,v); 69 else if (v>p->v) 70 return treap_find(p->right,v); 71 else 72 return p->weight; 73 } 74 75 void treap_insert(treap_node *&p,int v) 76 { 77 if (!p) 78 p=new_treap_node(v); 79 else 80 { 81 p->size++; 82 if (v < p->v) 83 { 84 treap_insert(p->left,v); 85 if (p->left->fix < p->fix) 86 treap_rotate_right(p); 87 } 88 else if (v > p->v) 89 { 90 treap_insert(p->right,v); 91 if (p->right->fix < p->fix) 92 treap_rotate_left(p); 93 } 94 else 95 p->weight++; 96 } 97 } 98 99 void treap_delete(treap_node *&p) //real deletion 100 { 101 if (p->left && p->right) 102 { 103 if (p->left->fix < p->right->fix) 104 { 105 treap_rotate_right(p); 106 treap_delete(p->right); 107 } 108 else 109 { 110 treap_rotate_left(p); 111 treap_delete(p->left); 112 } 113 } 114 else 115 { 116 if (p->left) 117 p=p->left; 118 else 119 p=p->right; 120 } 121 } 122 123 void treap_delete(treap_node *&p,int v) //lazy deletion 124 { 125 if (v==p->v) 126 { 127 p->weight--; 128 p->size--; 129 if (p->weight==0) 130 treap_delete(p); 131 } 132 else 133 { 134 if (v < p->v) 135 treap_delete(p->left,v); 136 else 137 treap_delete(p->right,v); 138 p->size--; 139 } 140 } 141 142 void treap_succ(treap_node *p,int v,int &rs) 143 { 144 if (!p) return; 145 if (p->v >= v) 146 { 147 rs=p->v; 148 treap_succ(p->left,v,rs); 149 } 150 else 151 treap_succ(p->right,v,rs); 152 } 153 154 int treap_getmin(treap_node *p) 155 { 156 while (p->left) 157 p=p->left; 158 return p->v; 159 } 160 161 int treap_getmax(treap_node *p) 162 { 163 while (p->right) 164 p=p->right; 165 return p->v; 166 } 167 168 void treap_rank(treap_node *p,int v,int cur,int &rank) 169 { 170 if (v == p->v) 171 rank=p->lsize() + cur + 1; 172 else if (v < p->v) 173 treap_rank(p->left,v,cur,rank); 174 else 175 treap_rank(p->right,v,p->lsize() + cur + p->weight,rank); 176 } 177 178 inline sgt_node* new_sgt_node() 179 { 180 SS[++SC].treap=0; 181 SS[SC].a=SS[SC].b=0; 182 SS[SC].left=SS[SC].right=0; 183 return &SS[SC]; 184 } 185 186 void sgt_build(sgt_node *&p,int a,int b) 187 { 188 p=new_sgt_node(); 189 if (a==b) 190 p->a=p->b=a; 191 else 192 { 193 int m=(a+b) >> 1; 194 sgt_build(p->left,a,m); 195 sgt_build(p->right,m+1,b); 196 p->a=a;p->b=b; 197 } 198 } 199 200 int sgt_edit(sgt_node *p,int k,int v,bool del) 201 { 202 int delter=0; 203 if (p->a==p->b) 204 { 205 if (del) 206 delter=p->treap->v; 207 } 208 else 209 { 210 int m=(p->a+p->b) >> 1; 211 if (k>=p->a && k<=m) 212 delter=sgt_edit(p->left,k,v,del); 213 else 214 delter=sgt_edit(p->right,k,v,del); 215 } 216 if (del) 217 treap_delete(p->treap,delter); 218 treap_insert(p->treap,v); 219 return delter; 220 } 221 222 void sgt_get(sgt_node *p,int a,int b) 223 { 224 if (p->a==a && p->b==b) 225 T[++Tcnt]=p->treap; 226 else 227 { 228 int m=(p->a+p->b) >> 1; 229 if (b<=m) 230 sgt_get(p->left,a,b); 231 else if (a>=m+1) 232 sgt_get(p->right,a,b); 233 else 234 { 235 sgt_get(p->left,a,m); 236 sgt_get(p->right,m+1,b); 237 } 238 } 239 } 240 241 242 int check(int result,int k) 243 { 244 int totalrankL,totalrankR,minsucc=INF; 245 int i,rank,succ,totalrank=0,totalcount=0; 246 for (i=1;i<=Tcnt;i++) 247 { 248 succ=INF; 249 treap_succ(T[i],result,succ); 250 if (succ==INF) 251 rank=T[i]->size+1; 252 else 253 treap_rank(T[i],succ,0,rank); 254 totalrank+=rank-1; 255 if (succ < minsucc) 256 minsucc=succ; 257 } 258 for (i=1;i<=Tcnt;i++) 259 totalcount+=treap_find(T[i],minsucc); 260 totalrankL=++totalrank; 261 totalrankR=totalrank+totalcount-1; 262 if (k>=totalrankL && k<=totalrankR) 263 { 264 printf("%d\n",minsucc); 265 return 0; 266 } 267 else if (totalrankL > k) 268 return 1; 269 else 270 return -1; 271 } 272 273 void binary(int a,int b,int k) 274 { 275 int Min=INF,Max=0,i,m,r; 276 Tcnt=0; 277 sgt_get(sgt_root,a,b); 278 for (i=1;i<=Tcnt;i++) 279 { 280 m=treap_getmax(T[i]); 281 if (m>Max) 282 Max=m; 283 m=treap_getmin(T[i]); 284 if (m<Min) 285 Min=m; 286 } 287 m=(Max+Min)>>1; 288 do 289 { 290 r=check(m,k); //-1=smaller 1=bigger 291 if (r<0) 292 { 293 Min=m; 294 m=(m+Max+1)>>1; 295 } 296 else if (r>0) 297 { 298 Max=m; 299 m=(Min+m)>>1; 300 } 301 }while (r!=0); 302 } 303 304 void request() 305 { 306 scanf ("%d", &M); 307 int i,a,b,c,j=0; 308 int op; 309 for (i=1;i<=M;i++) 310 { 311 scanf ("%d", &op); 312 if (op == 1) 313 { 314 scanf("%d%d",&a,&b); 315 sgt_edit(sgt_root,a,b,true); 316 } 317 else 318 { 319 scanf("%d%d%d",&a,&b,&c); 320 binary(a,b,c); 321 } 322 } 323 } 324 325 int main() 326 { 327 while (scanf ("%d", &N) == 1) { 328 int i,v; 329 TC=SC=-1; 330 sgt_root=0; 331 sgt_build(sgt_root,1,N); 332 for (i=1;i<=N;i++) 333 { 334 scanf("%d",&v); 335 sgt_edit(sgt_root,i,v,false); //non-deletion 336 } 337 request(); 338 } 339 340 return 0; 341 }