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

【分析】

裸题,不说了。

按照这种方法的话,离线的带插入修改区间第K大也应该可以做了。

不过这题的经典作法是树状数组上套可持久化线段树,不过这样空间消耗会很大。

可能要用动态开点?

转一个用块状链表的:http://www.cnblogs.com/zhj5chengfeng/archive/2013/08/19/3268162.html

  1. /*
  2. 宋代晏殊
  3. 《蝶恋花·槛菊愁烟兰泣露》
  4.  
  5. 槛菊愁烟兰泣露。罗幕轻寒,燕子双飞去。明月不谙离恨苦。斜光到晓穿朱户。
  6. 昨夜西风凋碧树。独上高楼,望尽天涯路。欲寄彩笺兼尺素。山长水阔知何处。
  7. */
  8. #include <iostream>
  9. #include <cstdio>
  10. #include <algorithm>
  11. #include <cstring>
  12. #include <vector>
  13. #include <utility>
  14. #include <iomanip>
  15. #include <string>
  16. #include <cmath>
  17. #include <queue>
  18. #include <assert.h>
  19. #include <map>
  20. #include <ctime>
  21. #include <cstdlib>
  22. #include <stack>
  23. #define LOCAL
  24. const int INF = ;
  25. const int MAXN = + ;
  26. using namespace std;
  27. struct QUERY{
  28. int x, y;
  29. int k, s, type, cur;//cur用来记录前面的值
  30. }q[MAXN], q1[MAXN], q2[MAXN];
  31. int Ans[MAXN];
  32. int tmp[MAXN], c[MAXN];
  33. int n, m, num, cnt;
  34. int data[MAXN];
  35.  
  36. inline int lowbit(int x){return x&-x;}
  37. void add(int x, int val){
  38. while (x <= n){
  39. c[x] += val;
  40. x += lowbit(x);
  41. }
  42. return;
  43. }
  44. int sum(int x){
  45. int cnt = ;
  46. while (x > ){
  47. cnt += c[x];
  48. x -= lowbit(x);
  49. }
  50. return cnt;
  51. }
  52. //整体二分
  53. void solve(int l, int r, int L, int R){
  54. //这两个都是结束条件
  55. if (l > r) return;
  56. if (L == R){//更新答案
  57. for (int i = l; i <= r; i++)
  58. if (q[i].type == ) Ans[q[i].s] = L;
  59. return;
  60. }
  61. int mid = (L + R) >> ;
  62. for (int i = l; i <= r; i++){
  63. if (q[i].type == && q[i].y <= mid) add(q[i].x, );
  64. else if (q[i].type == && q[i].y <= mid) add(q[i].x, -);
  65. else if (q[i].type == ) tmp[i] = sum(q[i].y) - sum(q[i].x - );
  66. }
  67. //更新完了就要清除标记了
  68. for (int i = l; i <= r; i++){
  69. if (q[i].type == && q[i].y <= mid) add(q[i].x, -);
  70. else if (q[i].type == && q[i].y <= mid) add(q[i].x, );
  71. }
  72. int l1 = , l2 = ;
  73. for (int i = l; i <= r; i++){
  74. if (q[i].type == ){
  75. //不用id就直接改
  76. if (q[i].cur + tmp[i] > q[i].k - ) q1[++l1] = q[i];
  77. else {
  78. q[i].cur += tmp[i];
  79. q2[++l2] = q[i];
  80. }
  81. }else{
  82. if (q[i].y <= mid) q1[++l1] = q[i];
  83. else q2[++l2] = q[i];
  84. }
  85. }
  86. for (int i = ; i <= l1; i++) q[i + l - ] = q1[i];
  87. for (int i = ; i <= l2; i++) q[i + l1 + l - ] = q2[i];
  88. solve(l, l + l1 - , L, mid);
  89. solve(l + l1, r, mid + , R);
  90. }
  91. void init(){
  92. memset(c, , sizeof(c));
  93. cnt = num = ;//指针初始化,num记录总的操作数量
  94. scanf("%d%d", &n, &m);
  95. for (int i = ; i <= n; i++){
  96. num++;
  97. scanf("%d", &data[i]);
  98. q[num].x = i;q[num].type = ;//1代表插入
  99. q[num].s = ;q[num].y = data[i];//没有用y就当val用
  100. }
  101. for (int i = ; i <= m; i++){
  102. char str[];
  103. num++;
  104. scanf("%s", str);
  105. if (str[] == 'Q'){
  106. int l, r, k;
  107. scanf("%d%d%d", &l, &r, &k);
  108. q[num].x = l;q[num].y = r;
  109. q[num].type = ; q[num].s = ++cnt;
  110. q[num].k = k;
  111. }else{
  112. int l, x;
  113. scanf("%d%d", &l, &x);
  114. q[num].x = l;q[num].y = data[l];//2为删除
  115. q[num].type = ;q[num].s = ;
  116. q[++num].x = l;
  117. q[num].y = x;//删除后插入
  118. q[num].type = ;
  119. q[num].s = ;
  120. data[l] = x;//注意这里一定要改,不然会影响到后面的更新
  121. }
  122. }
  123. for (int i = ; i <= num; i++) q[i].cur = ;
  124. }
  125.  
  126. int main(){
  127. int T;
  128.  
  129. scanf("%d", &T);
  130. while (T--){
  131. init();
  132. solve(, num, , INF);
  133. for (int i = ; i <= cnt; i++) printf("%d\n", Ans[i]);
  134. }
  135. return ;
  136. }

【ZOJ2112】【整体二分+树状数组】带修改区间第k大的更多相关文章

  1. 主席树套树状数组——带修区间第k大zoj2112

    主席树带修第k大 https://www.cnblogs.com/Empress/p/4659824.html 讲的非常好的博客 首先按静态第k大建立起一组权值线段树(主席树) 然后现在要将第i个值从 ...

  2. 【bzoj3110】[Zjoi2013]K大数查询 整体二分+树状数组区间修改

    题目描述 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c.如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数 ...

  3. 【BZOJ3110】【整体二分+树状数组区间修改/线段树】K大数查询

    Description 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c 如果是2 a b c形式,表示询问从第a个位置到第b个位 ...

  4. 【BZOJ-2527】Meteors 整体二分 + 树状数组

    2527: [Poi2011]Meteors Time Limit: 60 Sec  Memory Limit: 128 MBSubmit: 831  Solved: 306[Submit][Stat ...

  5. 【bzoj2527】[Poi2011]Meteors 整体二分+树状数组

    题目描述 有N个成员国.现在它发现了一颗新的星球,这颗星球的轨道被分为M份(第M份和第1份相邻),第i份上有第Ai个国家的太空站. 这个星球经常会下陨石雨.BIU已经预测了接下来K场陨石雨的情况.BI ...

  6. BZOJ_3110_[Zjoi2013]K大数查询_整体二分+树状数组

    BZOJ_3110_[Zjoi2013]K大数查询_整体二分+树状数组 Description 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位 ...

  7. 【bzoj4009】[HNOI2015]接水果 DFS序+树上倍增+整体二分+树状数组

    题目描述 给出一棵n个点的树,给定m条路径,每条路径有一个权值.q次询问求一个路径包含的所有给定路径中权值第k小的. 输入 第一行三个数 n和P 和Q,表示树的大小和盘子的个数和水果的个数. 接下来n ...

  8. 少年,想学带修改主席树吗 | BZOJ1901 带修改区间第k小

    少年,想学带修改主席树吗 | BZOJ1901 带修改区间第k小 有一道题(BZOJ 1901)是这样的:n个数,m个询问,询问有两种:修改某个数/询问区间第k小. 不带修改的区间第k小用主席树很好写 ...

  9. BZOJ 2527 [POI2011]MET-Meteors (整体二分+树状数组)

    题目大意:略 洛谷传送门 整体二分裸题 考虑只有一个国家的情况如何处理 对询问数量二分答案,暴力$O(m)$打差分,求前缀和验证,时间是$O(mlogK)$ 如果有$n$个国家,就是$O(nmlogK ...

随机推荐

  1. 【转】Android Fragment 基本介绍--不错

    原文网址:http://www.cnblogs.com/mengdd/archive/2013/01/08/2851368.html Fragment Android是在Android 3.0 (AP ...

  2. pojo类和vo类分别是什么

    转:http://blog.sina.com.cn/s/blog_4adc4b090101kuks.html vo有两种说法,一个是viewObject,一个是valueObject.. 就拿前者来说 ...

  3. [转]33 useful Keyboard Shortcuts for Run commond

    原文: http://www.shortcutworld.com/en/win/Run-command.html 1. Calling Run CommandWin + r               ...

  4. iOS 多线程学习笔记 —— GCD

    本文复制.参考自文章:iOS多线程编程之Grand Central Dispatch(GCD)介绍和使用 ,主要为了加强个人对知识的理解和记忆,不做他用.原作者声明: 著作权声明:本文由http:// ...

  5. ZOJ Problem Set - 3758 素数

    Singles' Day Time Limit: 2 Seconds Memory Limit: 65536 KB Singles' Day(or One's Day), an unofficial ...

  6. poj 2631 Roads in the North【树的直径裸题】

    Roads in the North Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 2359   Accepted: 115 ...

  7. android 随手记 倒计时

    class CountDownUtils extends CountDownTimer { public CountDownUtils(long millisInFuture, long countD ...

  8. 数据分析:Weka,Matlab,R,SPSS,SAS等分析软件的入门

    1 功能角度 weka是机器学习方面的工具(开源).spss是数学工具(商业工具). 具体的说,weka的主要功能是模式分类,或者模式识别或者回归.包括特征的降维(PCA),特征选择,训练模型以及对测 ...

  9. head first-----decorate design pattern

    浅谈设计模式之------装饰者模式     首先给出装饰者模式的定义吧:              动态的将责任附加到对象上,若是要扩展功能,装饰者提供了比继承更加具有弹性的替代方案.     其中 ...

  10. android 21 隐式意图启动系统预定义activity

    Intent intent=new Intent(LoginActivity.this, MainActivity.class);//显示意图启动,显示从一个activity到另一个activity, ...