ZOJ -2112 Dynamic Rankings 主席树 待修改的区间第K大
Posted Schenker
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ZOJ -2112 Dynamic Rankings 主席树 待修改的区间第K大相关的知识,希望对你有一定的参考价值。
带修改的区间第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\n", 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 Dynamic Rankings 主席树 待修改的区间第K大的主要内容,如果未能解决你的问题,请参考以下文章