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\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

原文地址:https://www.cnblogs.com/MingSD/p/9092632.html

时间: 2024-10-27 08:29:57

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

zoj 2112 Dynamic Rankings(主席树&amp;动态第k大)

Dynamic Rankings Time Limit: 10 Seconds      Memory Limit: 32768 KB The Company Dynamic Rankings has developed a new kind of computer that is no longer satisfied with the query like to simply find the k-th smallest number of the given N numbers. They

ZOJ 2112 Dynamic Rankings(主席树の动态kth)

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2112 The Company Dynamic Rankings has developed a new kind of computer that is no longer satisfied with the query like to simply find the k-th smallest number of the given N numbers. T

ZOJ 2112 Dynamic Rankings(主席树套树状数组+静态主席树)

题意:给定一个区间,求这个区间第k大的数,支持单点修改. 思路:主席树真是个神奇的东西.........速度很快但是也有一个问题就是占用内存的很大,一般来说支持单点修改的主席树套树状数组空间复杂度为O(n*logn*logn), 如果查询较少的话,可以初始的时候用一颗静态主席树,这样空间复杂度可以降为O(n*logn+q*logn*logn),勉强可以过zoj这道题. 这道题看了好久好久才懂...网上题解一般就几句话.......下面是自己的一些理解. 首先静态主席树这个东西其实比较好懂,就是对

zoj 2112 Dynamic Rankings(树状数组套主席树)

题意:对于一段区间,每次求[l,r]的第k大,存在单点修改操作: 思路: 学习主席树参考: http://blog.csdn.net/wjf_wzzc/article/details/24560117(各种形式) http://blog.csdn.net/bossup/article/details/31921235(推荐) http://blog.csdn.net/xiaofengcanyuexj/article/details/25553521?utm_source=tuicool(图解)

BZOJ 1901 Dynamic Rankings 主席树

题目大意:可修改的区间第k小 这个主席树卡了我两天...切掉Count On A Tree 之后我就一直认为带修改的主席树是树状数组套可持久化线段树...其实我被误导了... 尼玛带修改的主席树和可持久化线段树毛关系都木有啊!!! 那就是动态的权值线段树啊啊啊啊啊啊啊!!! 好吧这里给不明白主席树的孩纸一些简介: 1.外层树状数组 2.里层线段树 3.线段树动态开节点.仅此而已.和可持久化完全没关系. 4.一个点上的线段树和其他版本毛关系都没有. 5.正常按照普通的树套树往里插就行了. 7.询问

●ZOJ 2112 Dynamic Rankings

●赘述题目 对于一个长为n(n<50000)的序列(序列中的数小于1000000000),现有如下两种指令: Q a b c:询问区间[a,b]中第c小的数. C p b:将序列中的从左往右数第p个数改成b. ●题解 (整体二分应该可以做吧...但写不来了) 主席树+树状数组套线段树维护. 本题和POJ 2104 K-th Number相比,多了一个修改操作,但真的做得我心累. 看看POJ 2104 的查询函数: 查询区间到底是往左还是往右,这决于tmp与k大小关系.但本题因为有修改操作,导致上

zoj 2112 Dynamic Rankings 带修改区间第K大 动态主席树

pass 首先,个人觉得把这个数据结构理解成树状数组套主席树是十分不严谨的.主席树的本质是可持久化权值线段树与前缀和思想的结合.而动态主席树是可持久化权值线段树与树状数组思想的结合.并非树套树般的泾渭分明的叠加. 其次,大概讲下对动态主席树的理解.我们静态主席树中,第i个版本维护的是[1,i]的权值线段树,我们利用前缀和的思想,通过y的版本-x的版本得到[x,y]的权值线段树,从而剥离出一颗对应区间的权值线段树.我们考虑在这个情况下,如果需要修改第a[i]的值,那么从i,i+1,i+2.....

ZOJ 2112 Dynamic Rankings(树状数组+主席树)

The Company Dynamic Rankings has developed a new kind of computer that is no longer satisfied with the query like to simply find the k-th smallest number of the given N numbers. They have developed a more powerful system such that for N numbers a[1],

ZOJ 2112 Dynamic Rankings(带修改的区间第K大,分块+二分搜索+二分答案)

Dynamic Rankings Time Limit: 10 Seconds      Memory Limit: 32768 KB The Company Dynamic Rankings has developed a new kind of computer that is no longer satisfied with the query like to simply find the k-th smallest number of the given N numbers. They