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], a[2], ..., a[N], you can ask it like: what is the k-th smallest number of a[i], a[i+1], ..., a[j]? (For some i<=j, 0<k<=j+1-i that you have given to it). More powerful, you can even change
the value of some a[i], and continue to query, all the same.

Your task is to write a program for this computer, which

- Reads N numbers from the input (1 <= N <= 50,000)

- Processes M instructions of the input (1 <= M <= 10,000). These instructions include querying the k-th smallest number of a[i], a[i+1], ..., a[j] and change some a[i] to t.

Input

The first line of the input is a single number X (0 < X <= 4), the number of the test cases of the input. Then X blocks each represent a single test case.

The first line of each block contains two integers N and M, representing N numbers and M instruction. It is followed by N lines. The (i+1)-th line represents the number a[i]. Then M lines that is in the following format

Q i j k or

C i t

It represents to query the k-th number of a[i], a[i+1], ..., a[j] and change some a[i] to t, respectively. It is guaranteed that at any time of the operation. Any number a[i] is a non-negative integer that is less than 1,000,000,000.

There're NO breakline between two continuous test cases.

Output

For each querying operation, output one integer to represent the result. (i.e. the k-th smallest number of a[i], a[i+1],..., a[j])

There're NO breakline between two continuous test cases.

Sample Input

2

5 3

3 2 1 4 7

Q 1 4 3

C 2 6

Q 2 5 3

5 3

3 2 1 4 7

Q 1 4 3

C 2 6

Q 2 5 3

Sample Output

3

6

3

6

题意:给你一个长为n的区间,有m个询问和修改,每次把下标i对应的值改变,或者询问某段区间的第k小值。

思路:这题是很经典的题,可以用主席树和树套树做,对于树套树的做法,我是用线段树的每一个节点都存一个treap,然后每一次修改就是单点更新,修改的时间复杂度为O(n*logn*logn),询问时,需要二分值val,并统计线段树中对应的区间小于val值的个数,询问的时间复杂度为O(n*logn*logn*logn),所以总的时间复杂度为O(n*logn*logn*logn),同时因为线段树最多有logn层,每层都是n个节点,所以treap的空间复杂度为O(n*logn).

  1. #include<iostream>
  2. #include<stdio.h>
  3. #include<stdlib.h>
  4. #include<string.h>
  5. #include<math.h>
  6. #include<vector>
  7. #include<map>
  8. #include<set>
  9. #include<string>
  10. #include<bitset>
  11. #include<algorithm>
  12. using namespace std;
  13. #define lson th<<1
  14. #define rson th<<1|1
  15. typedef long long ll;
  16. typedef long double ldb;
  17. #define inf 99999999
  18. #define pi acos(-1.0)
  19. #define maxn 50005
  20. int rt[maxn*4],a[maxn],n;
  21. int cnt;
  22. struct Treap{
  23. int key,pri,siz,num,son[2];
  24. void newnode(int x,int y){
  25. key=x;pri=y;
  26. siz=num=1;
  27. son[0]=son[1]=0;
  28. }
  29. }T[20*maxn];
  30. void rotate(int p,int &x)
  31. {
  32. int y=T[x].son[!p];
  33. T[x].siz=T[x].siz-T[y].siz+T[T[y].son[p] ].siz;
  34. T[x].son[!p]=T[y].son[p];
  35. T[y].siz=T[y].siz-T[T[y].son[p] ].siz+T[x].siz;
  36. T[y].son[p]=x;
  37. x=y;
  38. }
  39. void charu(int key,int &x)
  40. {
  41. if(x==0){
  42. x=++cnt;
  43. T[x].newnode(key,rand());
  44. }
  45. else{
  46. T[x].siz++;
  47. if(T[x].key==key){
  48. T[x].num++;return;
  49. }
  50. int p=key<T[x].key;
  51. charu(key,T[x].son[!p]);
  52. if(T[x].pri<T[T[x].son[!p] ].pri )
  53. rotate(p,x);
  54. }
  55. }
  56. void del(int key, int &x)
  57. {
  58. if(T[x].key == key)
  59. {
  60. if(T[x].num>1){
  61. T[x].siz--;
  62. T[x].num--;
  63. return;
  64. }
  65. if(T[x].son[0] && T[x].son[1])
  66. {
  67. int p=T[T[x].son[0]].pri>T[T[x].son[1]].pri;
  68. rotate(p,x);
  69. del(key,x);
  70. }
  71. else x=T[x].son[1]+T[x].son[0];
  72. }
  73. else
  74. {
  75. T[x].siz--;
  76. int p=T[x].key>key;
  77. del(key,T[x].son[!p]);
  78. }
  79. }
  80. int query_rank(int key,int &x)
  81. {
  82. if(x==0)return 0;
  83. if(T[x].key==key)return T[T[x].son[0] ].siz;
  84. if(T[x].key>key)return query_rank(key,T[x].son[0]);
  85. if(T[x].key<key)return T[T[x].son[0] ].siz+T[x].num+query_rank(key,T[x].son[1]);
  86. }
  87. void update(int idx,int val,int L,int R,int th,int f)
  88. {
  89. if(f)del(a[idx],rt[th]);
  90. charu(val,rt[th]);
  91. if(L==idx && R==idx){
  92. a[idx]=val;
  93. return;
  94. }
  95. int mid=(L+R)/2;
  96. if(idx<=mid)update(idx,val,L,mid,lson,f);
  97. else update(idx,val,mid+1,R,rson,f);
  98. }
  99. int question(int l,int r,int val,int L,int R,int th)
  100. {
  101. int mid;
  102. if(l==L && r==R){
  103. return query_rank(val,rt[th]);
  104. }
  105. mid=(L+R)/2;
  106. if(r<=mid)return question(l,r,val,L,mid,lson);
  107. else if(l>mid)return question(l,r,val,mid+1,R,rson);
  108. else return question(l,mid,val,L,mid,lson)+question(mid+1,r,val,mid+1,R,rson);
  109. }
  110. int main()
  111. {
  112. int m,i,j,Tcase,l,r,c,d,e,mid;
  113. char s[10];
  114. scanf("%d",&Tcase);
  115. while(Tcase--)
  116. {
  117. memset(rt,0,sizeof(rt));
  118. scanf("%d%d",&n,&m);
  119. for(i=1;i<=n;i++){
  120. scanf("%d",&a[i]);
  121. }
  122. cnt=0;
  123. for(i=1;i<=n;i++){
  124. update(i,a[i],1,n,1,0);
  125. }
  126. for(i=1;i<=m;i++){
  127. scanf("%s",s);
  128. if(s[0]=='C'){
  129. scanf("%d%d",&c,&d);
  130. update(c,d,1,n,1,1);
  131. }
  132. else{
  133. scanf("%d%d%d",&c,&d,&e);
  134. l=0;r=1000000000;
  135. while(l<=r){
  136. mid=(l+r)/2;
  137. //printf("%d %d %d\n",l,r,mid);
  138. if(question(c,d,mid,1,n,1)>=e)r=mid-1;
  139. else l=mid+1;
  140. }
  141. printf("%d\n",r);
  142. }
  143. }
  144. }
  145. return 0;
  146. }
  147. /*
  148. 2
  149. 5 3
  150. 3 2 1 4 7
  151. Q 1 4 3
  152. C 2 6
  153. Q 2 5 3
  154. 5 3
  155. 3 2 1 4 7
  156. Q 1 4 3
  157. C 2 6
  158. Q 2 5 3
  159. */

主席树做法:

  1. #include<iostream>
  2. #include<stdio.h>
  3. #include<stdlib.h>
  4. #include<string.h>
  5. #include<math.h>
  6. #include<vector>
  7. #include<map>
  8. #include<set>
  9. #include<string>
  10. #include<bitset>
  11. #include<algorithm>
  12. using namespace std;
  13. typedef long long ll;
  14. typedef long double ldb;
  15. #define lth th<<1
  16. #define rth th<<1|1
  17. #define inf 99999999
  18. #define pi acos(-1.0)
  19. #define maxn 60005
  20. #define M 2500010
  21. int a[maxn],n;
  22. struct node{
  23. int l,r,kind,d;
  24. }ques[10005];
  25. int pos[maxn],T[maxn],S[maxn];
  26. int lson[M],rson[M],c[M];
  27. int th,tot;
  28. int build(int l,int r)
  29. {
  30. int newroot=++th,i,j,mid;
  31. c[newroot]=0; //!!!
  32. if(l!=r){
  33. mid=(l+r)/2;
  34. lson[newroot]=build(l,mid);
  35. rson[newroot]=build(mid+1,r);
  36. }
  37. return newroot;
  38. }
  39. int update(int root,int zhi,int value)
  40. {
  41. int i,j;
  42. int newroot=++th;int tmp=newroot;
  43. int l=1,r=tot,mid;
  44. c[newroot]=c[root]+value;
  45. while(l<r){
  46. mid=(l+r)/2;
  47. if(zhi<=mid){
  48. r=mid;
  49. lson[newroot ]=++th;rson[newroot]=rson[root];
  50. newroot=lson[newroot];root=lson[root];
  51. }
  52. else{
  53. l=mid+1;
  54. lson[newroot ]=lson[root];rson[newroot]=++th;
  55. newroot=rson[newroot];root=rson[root];
  56. }
  57. c[newroot]=c[root]+value;
  58. }
  59. return tmp;
  60. }
  61. int lowbit(int x)
  62. {
  63. return x&(-x);
  64. }
  65. void modify(int pos,int zhi,int value)
  66. {
  67. int i,j;
  68. while(pos<=n){
  69. S[pos]=update(S[pos],zhi,value);
  70. pos+=lowbit(pos);
  71. }
  72. }
  73. int use[maxn];
  74. int getsum(int pos)
  75. {
  76. int sum=0;
  77. while(pos>0){
  78. sum+=c[lson[use[pos] ] ];
  79. pos-=lowbit(pos);
  80. }
  81. return sum;
  82. }
  83. int question(int left,int right,int k)
  84. {
  85. int i,j,root1,root2;
  86. int l=1,r=tot,mid;
  87. for(i=left-1;i>0;i-=lowbit(i))use[i]=S[i];
  88. for(i=right;i>0;i-=lowbit(i))use[i]=S[i];
  89. root1=T[left-1];root2=T[right];
  90. while(l<r){
  91. mid=(l+r)/2;
  92. int tmp=getsum(right)-getsum(left-1)+c[lson[root2] ]-c[lson[root1] ];
  93. if(tmp>=k){
  94. r=mid;
  95. root1=lson[root1];root2=lson[root2];
  96. for(i=left-1;i>0;i-=lowbit(i))use[i]=lson[use[i] ];
  97. for(i=right;i>0;i-=lowbit(i))use[i]=lson[use[i] ];
  98. }
  99. else{
  100. k-=tmp;
  101. l=mid+1;
  102. root1=rson[root1];root2=rson[root2];
  103. for(i=left-1;i>0;i-=lowbit(i))use[i]=rson[use[i] ];
  104. for(i=right;i>0;i-=lowbit(i))use[i]=rson[use[i] ];
  105. }
  106. }
  107. return l;
  108. }
  109. int main()
  110. {
  111. int m,i,j,Tcase,c,d,e;
  112. char str[5];
  113. scanf("%d",&Tcase);
  114. while(Tcase--)
  115. {
  116. scanf("%d%d",&n,&m);
  117. tot=0;
  118. for(i=1;i<=n;i++){
  119. scanf("%d",&a[i]);
  120. tot++;
  121. pos[tot]=a[i];
  122. }
  123. for(i=1;i<=m;i++){
  124. scanf("%s",str);
  125. if(str[0]=='Q'){
  126. scanf("%d%d%d",&c,&d,&e);
  127. ques[i].kind=0;ques[i].l=c;ques[i].r=d;ques[i].d=e;
  128. }
  129. else if(str[0]=='C'){
  130. scanf("%d%d",&c,&d);
  131. tot++;pos[tot]=d;
  132. ques[i].kind=1;ques[i].l=c;ques[i].r=d;
  133. }
  134. }
  135. sort(pos+1,pos+1+tot);
  136. tot=unique(pos+1,pos+1+tot)-pos-1;
  137. th=0;
  138. T[0]=build(1,tot);
  139. for(i=1;i<=n;i++){
  140. int t=lower_bound(pos+1,pos+1+tot,a[i])-pos;
  141. T[i]=update(T[i-1],t,1);
  142. }
  143. for(i=1;i<=n;i++){
  144. S[i]=T[0];
  145. }
  146. for(i=1;i<=m;i++){
  147. if(ques[i].kind==0){ //表示询问
  148. printf("%d\n",pos[question(ques[i].l,ques[i].r,ques[i].d)]);
  149. }
  150. else{
  151. int t1=lower_bound(pos+1,pos+1+tot,a[ques[i].l])-pos;
  152. int t2=lower_bound(pos+1,pos+1+tot,ques[i].r)-pos;
  153. modify(ques[i].l,t1,-1);
  154. modify(ques[i].l,t2,1);
  155. a[ques[i].l ]=ques[i].r; //!!!
  156. }
  157. }
  158. }
  159. return 0;
  160. }
  161. /*
  162. 2
  163. 5 3
  164. 3 2 1 4 7
  165. Q 1 4 3
  166. C 2 6
  167. Q 2 5 3
  168. 5 3
  169. 3 2 1 4 7
  170. Q 1 4 3
  171. C 2 6
  172. Q 2 5 3
  173. */

zoj2112 Dynamic Rankings (主席树 || 树套树)的更多相关文章

  1. ZOJ2112 Dynamic Rankings (线段树套平衡树)(主席树)

    The Company Dynamic Rankings has developed a new kind of computer that is no longer satisfied with t ...

  2. [bzoj1901][zoj2112][Dynamic Rankings] (整体二分+树状数组 or 动态开点线段树 or 主席树)

    Dynamic Rankings Time Limit: 10 Seconds      Memory Limit: 32768 KB The Company Dynamic Rankings has ...

  3. Bzoj 1901: Zju2112 Dynamic Rankings 主席树,可持久,树状数组,离散化

    1901: Zju2112 Dynamic Rankings Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 6321  Solved: 2628[Su ...

  4. 【BZOJ1901】Zju2112 Dynamic Rankings 主席树+树状数组

    [BZOJ1901]Zju2112 Dynamic Rankings Description 给定一个含有n个数的序列a[1],a[2],a[3]……a[n],程序必须回答这样的询问:对于给定的i,j ...

  5. 洛谷P2617 Dynamic Rankings (主席树)

    洛谷P2617 Dynamic Rankings 题目描述 给定一个含有n个数的序列a[1],a[2],a[3]--a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a ...

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

    Dynamic Rankings Time Limit: 10 Seconds      Memory Limit: 32768 KB The Company Dynamic Rankings has ...

  7. bzoj 1901: Zju2112 Dynamic Rankings -- 主席树,树状数组,哈希

    1901: Zju2112 Dynamic Rankings Time Limit: 10 Sec  Memory Limit: 128 MB Description 给定一个含有n个数的序列a[1] ...

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

    Dynamic Rankings 带修改的区间第K大其实就是先和静态区间第K大的操作一样.先建立一颗主席树, 然后再在树状数组的每一个节点开线段树(其实也是主席树,共用节点), 每次修改的时候都按照树 ...

  9. ZOJ2112 Dynamic Rankings(整体二分)

    今天学习了一个奇技淫巧--整体二分.关于整体二分的一些理论性的东西,可以参见XRH的<浅谈数据结构题的几个非经典解法>.然后下面是一些个人的心得体会吧,写下来希望加深一下自己的理解,或者如 ...

随机推荐

  1. Java安全之Weblogic 2016-3510 分析

    Java安全之Weblogic 2016-3510 分析 首发安全客:Java安全之Weblogic 2016-3510 分析 0x00 前言 续前面两篇文章的T3漏洞分析文章,继续来分析CVE-20 ...

  2. Java实现开根号运算(不使用数组和String)

    使用Java自己实现开根号运算,网上也有不少代码,多数都使用String或者数组.这里写一段只使用double基础数据类型实现的方法. private static double sqrt(int n ...

  3. 【MySQL 基础】MySQ LeetCode

    MySQL LeetCode 175. 组合两个表 题目描述 表1: Person +-------------+---------+ | 列名 | 类型 | +-------------+----- ...

  4. python模块详解 | pyquery

    简介 pyquery是一个强大的 HTML 解析库,利用它,我们可以直接解析 DOM 节点的结构,并通过 DOM 节点的一些属性快速进行内容提取. 官方文档:http://pyquery.readth ...

  5. 【Spring】Spring中的Bean - 5、Bean的装配方式(XML、注解(Annotation)、自动装配)

    Bean的装配方式 简单记录-Java EE企业级应用开发教程(Spring+Spring MVC+MyBatis)-Spring中的Bean 文章目录 Bean的装配方式 基于XML的装配 基于注解 ...

  6. 原生工程接入Flutter实现混编

    前言 上半年我定的OKR目标是帮助团队将App切入Flutter,实现统一技术栈,变革成多端融合开发模式.Flutter目前是跨平台方案中最有潜力实现我们这个目标的,不管是Hybird还是React ...

  7. kubernets之计算资源

    一  为pod分配cpu,内存以及其他的资源 1.1  创建一个pod,同时为这个pod分配内存以及cpu的资源请求量 apiVersion: v1 kind: Pod metadata: name: ...

  8. disfunc绕过

    绕过DisFunc的常见小技巧 解析webshell命令不能执行时的三大情况 一是 php.ini 中用 disable_functions 指示器禁用了 system().exec() 等等这类命令 ...

  9. centos7+宝塔+ssrpanel v3 魔改版 前后端配置教程

    一.服务端 1.安装宝塔 登录 SSH 后,直接安装宝塔. yum install -y wget && wget -O install.sh http://download.bt.c ...

  10. 写给 Linux 初学者的一封信

    大家好,我是肖邦. 这篇文章是写给 Linux 初学者的,我会分享一些作为初学者应该知道的一些东西,这些内容都是本人从事 Linux 开发工作多年的心得体会,相信会对初学者有所帮助.如果你是 Linu ...