CRB and Queries(动态区间求第k小数模板题:线段树套平衡树)

来源:互联网 发布:如何做好商务工作 知乎 编辑:程序博客网 时间:2024/05/19 20:45


Link:http://acm.hdu.edu.cn/showproblem.php?pid=5412

CRB and Queries

Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 1184    Accepted Submission(s): 299


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 A1A2, …, 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 ≤ NQ ≤ 105
1 ≤ Aiv ≤ 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
51 2 3 4 532 2 4 21 3 62 2 4 2
 

Sample Output
34
 

Author
KUT(DPRK)
 

Source
2015 Multi-University Training Contest 10
 

AC code:

#include <cstdio>#include <cstring>#include <cstdlib>#include <iostream>#include <algorithm>using namespace std;#define N 1000007#define M 1000007#define INF 1000000000char ctrl[M][3];int cnt,n,m;int P[M],Q[M],a[N],b[N],K[M];struct treap{   int key,wei,cnt,size,ch[2];}T[N * 15];int tree[N << 1],nodecnt,root;void init(){   T[0].size = 0;   T[0].wei = -INF;   nodecnt = root = 0;}int ID(int l,int r){return l + r | l != r;}void update(int x){   T[x].size = T[T[x].ch[0]].size + T[T[x].ch[1]].size + T[x].cnt;}void rotate(int &x,int t){   int y = T[x].ch[t];   T[x].ch[t] = T[y].ch[!t];   T[y].ch[!t] = x;   update(x);   update(y);   x = y;}void insert(int &x,int t){   if (!x){       x = ++ nodecnt;       T[x].key = t;       T[x].wei = rand();       T[x].cnt = 1;       T[x].ch[0] = T[x].ch[1] = 0;   }else if (T[x].key == t) T[x].cnt ++;   else{       int k = T[x].key < t;       insert(T[x].ch[k],t);       if (T[x].wei < T[T[x].ch[k]].wei) rotate(x,k);   }   update(x);}void erase(int &x,int t){   if (T[x].key == t){       if (T[x].cnt == 1){           if (!T[x].ch[0] && !T[x].ch[1]) {               x = 0;return;           }           rotate(x,T[T[x].ch[0]].wei < T[T[x].ch[1]].wei);           erase(x,t);       }else T[x].cnt --;   }else erase(T[x].ch[T[x].key < t],t);   update(x);}int select(int x,int t){   if (!x) return 0;   if (T[x].key > t) return select(T[x].ch[0],t);   return T[x].cnt + T[T[x].ch[0]].size + select(T[x].ch[1],t);}void treeins(int l,int r,int i,int x){   insert(tree[ID(l,r)],x);   if (l == r) return;   int m = l + r >> 1;   if (i <= m) treeins(l,m,i,x);   else treeins(m + 1,r,i,x);}void treedel(int l,int r,int i,int x){   erase(tree[ID(l,r)],x);   if (l == r) return;   int m = l + r >> 1;   if (i <= m) treedel(l,m,i,x);   else treedel(m + 1,r,i,x);}int query(int l,int r,int x,int y,int t){   if (l == r) return l;   int m = l + r >> 1;   int ans = select(tree[ID(l,m)],y) - select(tree[ID(l,m)],x);   if (ans >= t) return query(l,m,x,y,t);   return query(m + 1,r,x,y,t - ans);}int main(){   //freopen("in.txt","r",stdin);   int Times;   while (scanf("%d",&n)!=EOF){       memset(tree,0,sizeof tree);       init();       cnt = 0;       for (int i = 1;i <= n;i ++) scanf("%d",&a[i]),b[++ cnt] = a[i];       scanf("%d",&m);       for (int i = 1;i <= m;i ++){           scanf("%s%d%d",ctrl[i],&P[i],&Q[i]);           if (ctrl[i][0] == '2') scanf("%d",&K[i]);           else b[++ cnt] = Q[i];       }       sort(b + 1,b + 1 + cnt);       cnt = unique(b + 1,b + 1 + cnt) - b - 1;       for (int i = 1;i <= n;i ++) {           a[i] = lower_bound(b + 1,b + 1 + cnt,a[i]) - b;           treeins(1,cnt,a[i],i);       }       for (int i = 1;i <= m;i ++){           if (ctrl[i][0] == '2'){               int id = query(1,cnt,P[i] - 1,Q[i],K[i]);               printf("%d\n",b[id]);           }else{               treedel(1,cnt,a[P[i]],P[i]);               a[P[i]] = lower_bound(b + 1,b + 1 + cnt,Q[i]) - b;               treeins(1,cnt,a[P[i]],P[i]);           }       }   }   return 0;}


0 0
原创粉丝点击