ZOJ -2112 Dynamic Rankings 主席树 待修改的区间第K大

Dynamic Rankings 

带修改的区间第K大其实就是先和静态区间第K大的操作一样。先建立一颗主席树, 然后再在树状数组的每一个节点开线段树(其实也是主席树,共用节点), 每次修改的时候都按照树状数组的方式去修改,并且修改那些地方。查询的时候就是查询原主席树+树状数组的值。

代码:

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
  4 #define LL long long
  5 #define ULL unsigned LL
  6 #define fi first
  7 #define se second
  8 #define pb push_back
  9 //#define lson l,m,rt<<1
 10 //#define rson m+1,r,rt<<1|1
 11 #define max3(a,b,c) max(a,max(b,c))
 12 #define min3(a,b,c) min(a,min(b,c))
 13 typedef pair<int,int> pll;
 14 const int INF = 0x3f3f3f3f;
 15 const LL mod =  (int)1e9+7;
 16 const int N = 60010;
 17 const int M = 2500010;
 18 int root[N], S[N], lson[M], rson[M], ll[N], rr[N], cnt[M];
 19 int tot, t;
 20 int lsz, rsz;
 21 int a[N], b[N];
 22 struct Node{
 23     int l, r, op, k;
 24 }A[N];
 25 int Build(int l, int r){
 26     int now = ++tot;
 27     cnt[now] = 0;
 28     if(l < r){
 29         int m = l+r >> 1;
 30         lson[now] = Build(l,m);
 31         rson[now] = Build(m+1,r);
 32     }
 33     return now;
 34 }
 35 int Update(int l, int r, int pre, int pos, int v){
 36     int now = ++tot;
 37     cnt[now] = cnt[pre] + v;
 38     if(l < r){
 39         int m = l+r >> 1;
 40         if(pos <= m){
 41             rson[now] = rson[pre];
 42             lson[now] = Update(l, m, lson[pre], pos, v);
 43         }
 44         else {
 45             lson[now] = lson[pre];
 46             rson[now] = Update(m+1, r, rson[pre], pos, v);
 47         }
 48         cnt[now] = cnt[lson[now]] + cnt[rson[now]];
 49     }
 50     return now;
 51 }
 52 int Query(int l, int r, int L, int R, int k){
 53     if(l == r) return l;
 54     int num1 = cnt[lson[L]];
 55     int num2 = cnt[lson[R]];
 56     for(int i = 1; i <= lsz; i++) num1 += cnt[lson[ll[i]]];
 57     for(int i = 1; i <= rsz; i++) num2 += cnt[lson[rr[i]]];
 58     num2 -= num1;
 59     int m = l+r >> 1;
 60     if(num2 >= k){
 61         for(int i = 1; i <= lsz; i++) ll[i] = lson[ll[i]];
 62         for(int i = 1; i <= rsz; i++) rr[i] = lson[rr[i]];
 63         return Query(l, m, lson[L], lson[R], k);
 64     }
 65     else {
 66         for(int i = 1; i <= lsz; i++) ll[i] = rson[ll[i]];
 67         for(int i = 1; i <= rsz; i++) rr[i] = rson[rr[i]];
 68         return Query(m+1, r, rson[L], rson[R], k-num2);
 69     }
 70 }
 71 int id(int x){
 72     return lower_bound(b+1, b+1+t, x) - b;
 73 }
 74 int lowbit(int x){
 75     return x&(-x);
 76 }
 77 int main(){
 78     int T;
 79     scanf("%d", &T);
 80     while(T--){
 81         tot = t = 0;
 82         int n, m;
 83         char s[5];
 84         scanf("%d%d", &n, &m);
 85         for(int i = 1; i <= n; i++) scanf("%d", &a[i]), b[++t] = a[i];
 86         for(int i = 1; i <= m; i++){
 87             scanf("%s", s);
 88             if(s[0] == 'Q'){
 89                 A[i].op = 1;
 90                 scanf("%d%d%d", &A[i].l, &A[i].r, &A[i].k);
 91             }
 92             else {
 93                 A[i].op = 2;
 94                 scanf("%d%d", &A[i].l, &A[i].r);
 95                 b[++t] = A[i].r;
 96             }
 97         }
 98         sort(b+1, b+1+t);
 99         int tmp = 0;
100         for(int i = 1; i <= t; i++)
101             if(b[i] != b[i-1]) b[++tmp] = b[i];
102         t = tmp;
103         root[0] = Build(1, t);
104         for(int i = 1; i <= n; i++){
105             root[i] = Update(1, t, root[i-1], id(a[i]), 1);
106         }
107         for(int i = 0; i <= n; i++) S[i] = root[0];
108         for(int i = 1; i <= m; i++){
109             if(A[i].op == 1){
110                 lsz = rsz = 0;
111                 for(int j = A[i].l-1; j; j-=lowbit(j)) ll[++lsz] = S[j];
112                 for(int j = A[i].r; j; j-=lowbit(j)) rr[++rsz] = S[j];
113                 printf("%d
", b[Query(1,t,root[A[i].l-1], root[A[i].r], A[i].k)]);
114             }
115             else {
116                 for(int j = A[i].l; j <= t; j += lowbit(j)) S[j] = Update(1, t, S[j], id(a[A[i].l]), -1);
117                 for(int j = A[i].l; j <= t; j += lowbit(j)) S[j] = Update(1, t, S[j], id(A[i].r), 1);
118                 a[A[i].l] = A[i].r;
119             }
120         }
121     }
122     return 0;
123 }
ZOJ 2112
原文地址:https://www.cnblogs.com/MingSD/p/9092632.html