题目链接:

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1112

题意:

求动态区间第K大。

分析:

把修改操作看成删除与增加,对所有操作进行整体二分。

代码:

  1. #include<cstdio>
  2. #include<iostream>
  3. #include<cstring>
  4. using namespace std;
  5. #define pr(x) cout << #x << ": " << x << " "
  6. #define pl(x) cout << #x << ": " << x << endl;
  7. const int maxn = 50000 + 5, maxq = 20000 + 5, oo = 0x3f3f3f3f;
  8. int n, m, tot;
  9. int a[maxn];
  10. struct Query{
  11. int x, y, k;
  12. int id, type;
  13. }q[maxn + maxq], q1[maxn + maxq], q2[maxn + maxq];
  14. int bit[maxn];
  15. int ans[maxq];
  16. void add(int i, int x)
  17. {
  18. while(i <= n){
  19. bit[i] += x;
  20. i += i & -i;
  21. }
  22. }
  23. int sum(int i)
  24. {
  25. int ans = 0;
  26. while(i > 0){
  27. ans += bit[i];
  28. i -= i & -i;
  29. }
  30. return ans;
  31. }
  32. void solve(int ql, int qr, int l, int r)
  33. {
  34. if(ql > qr) return ;
  35. if(l == r){
  36. for(int i = ql; i <= qr; i++){
  37. if(q[i].type == 2) ans[q[i].id] = l;
  38. }
  39. return ;
  40. }
  41. int t1 = 0, t2 = 0;
  42. int mid = l + r >> 1;
  43. // pl(mid);
  44. for(int i = ql; i <= qr; i++){
  45. if(q[i].type == 1){
  46. if(q[i].x <= mid){
  47. add(q[i].id, q[i].y);
  48. q1[t1++] = q[i];
  49. }else q2[t2++] = q[i];
  50. }else{
  51. int tmp = sum(q[i].y) -sum(q[i].x - 1);
  52. if(tmp >= q[i].k) q1[t1++] = q[i];
  53. else {
  54. q[i].k -= tmp;
  55. q2[t2++] = q[i];
  56. }
  57. }
  58. }
  59. for(int i = 0; i < t1; i++){
  60. if(q1[i].type == 1) add(q1[i].id, -q1[i].y);
  61. }
  62. for(int i = 0; i < t1; i++) q[ql + i] = q1[i];
  63. for(int i = 0; i < t2; i++) q[t1 + i + ql] = q2[i];
  64. solve(ql, ql + t1 - 1, l, mid);
  65. solve(ql + t1, qr, mid + 1, r);
  66. }
  67. int main (void)
  68. {
  69. int x;scanf("%d", &x);
  70. while(x--){
  71. scanf("%d%d", &n, &m);
  72. tot = 0;
  73. memset(bit, 0, sizeof(bit));
  74. for(int i = 1; i <= n; i++){
  75. scanf("%d", &a[i]);
  76. q[++tot] = (Query){a[i], 1, oo, i, 1};
  77. }
  78. char s[2];
  79. int x, y, k;
  80. int cnt = 0;
  81. for(int i = 1; i <= m; i++){
  82. scanf("%s%d%d", s, &x, &y);
  83. if(s[0] == 'Q'){
  84. scanf("%d", &k);
  85. q[++tot] = (Query){x, y, k, ++cnt, 2};
  86. }else{
  87. q[++tot] = (Query){a[x], -1, oo, x, 1};
  88. q[++tot] = (Query){y, 1, oo, x, 1};
  89. }
  90. }
  91. solve(1, tot, 0, oo);
  92. for(int i = 1; i <= cnt; i++){
  93. printf("%d\n", ans[i]);
  94. }
  95. }
  96. return 0;
  97. }

ZOJ 1112 Dynamic Rankings【动态区间第K大,整体二分】的更多相关文章

  1. 51nod 1175 区间第k大 整体二分

    题意: 一个长度为N的整数序列,编号0 - N - 1.进行Q次查询,查询编号i至j的所有数中,第K大的数是多少. 分析: 仅仅就是一道整体二分的入门题而已,没听说过整体二分? 其实就是一个分治的函数 ...

  2. ZOJ2112 Dynamic Rankings 动态区间第K最值 平方分割

    有了上一题的经验(POJ的静态区间第K最值)再解决这道题就轻松多了 空间5256KB,时间3330ms,如果把动态开点的平衡树换成数组模拟的话应该会更快 之所以选择了平方分割而不是树套树,不仅是所谓趁 ...

  3. ZOJ2112--Dynamic Rankings (动态区间第k大)

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

  4. ZOJ 2112 Dynamic Rankings(动态区间第 k 大+块状链表)

    题目大意 给定一个数列,编号从 1 到 n,现在有 m 个操作,操作分两类: 1. 修改数列中某个位置的数的值为 val 2. 询问 [L, R] 这个区间中第 k 大的是多少 n<=50,00 ...

  5. hdu5412(动态区间第k大)

    CRB and Queries Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Other ...

  6. zoj 2112 Dynamic Rankings 动态第k大 线段树套Treap

    Dynamic Rankings Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.zju.edu.cn/onlinejudge/show ...

  7. 【BZOJ】1901: Zju2112 Dynamic Rankings(区间第k小+树套树)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1901 这题调了我相当长的时间,1wa1a,我是第一次写树套树,这个是树状数组套splay,在每个区间 ...

  8. 动态区间第K大

    整体二分. 主要需要注意的一点是,对于每个删除操作,若删除操作被算入贡献,则最开始的插入操作也一定会被算入,所以不必担心删除删错. #include<cstdio> #include< ...

  9. 【XSY2720】区间第k小 整体二分 可持久化线段树

    题目描述 给你你个序列,每次求区间第\(k\)小的数. 本题中,如果一个数在询问区间中出现了超过\(w\)次,那么就把这个数视为\(n\). 强制在线. \(n\leq 100000,a_i<n ...

随机推荐

  1. shell脚本,awk合并一列的问题。

    文件 file2内容如下:0 qwert1 asdfghjk2 asdjkl2 zxcvbn3 dfghjkll4 222224 tyuiop4 bnm 让第一列相等的合并成一行,不要第一列,也就是变 ...

  2. shell脚本,计算1+2+3+....100等于多少?

    第一种方法,通过for循环来计算[root@localhost wyb]# cat yibai.sh #!/bin/bash #从1+++...100的结果 i= ` do sum=$(($sum+i ...

  3. 浮动的label

    在web项目中,有一个很重的模块就是登陆/注册模块,这个模块的主体部分就是一个form表单,这个form表单包含两个重要input组(用户名/密码),每个input组都包含label和input,而关 ...

  4. Cookies和Session的区别和理解

    Cookies和Session的区别和理解 cookie机制 Cookies是服务器在本地机器上存储的小段文本并随每一个请求发送至同一个服务器.IETF RFC 2965 HTTP State Man ...

  5. perl学习之:匹配修饰符/s /m

    m 是将字符串作为多行处理,s是将字符串作为单行处理,如果是s在字符串中出现的\n就相当于普通字符. 6.6. Matching Within Multiple Lines6.6.1. Problem ...

  6. Python解释器镜像源修改

    目录 Windows Mac 这篇文章将解除你使用python的pip install xxx受到的网速限制,如果只是下载较小的第三方库,可以尝试pip --default-timeout=100 i ...

  7. 包含min的栈

    #include <iostream> #include <stack> using namespace std; void push(stack<int> &am ...

  8. 163 AJAX

    // 163 AJAX Tab // update 2006.10.18 // 增加鼠标延迟感应特性. // update 2006.10.8 // A 标签 href 属性将保持原有HTML功能.增 ...

  9. 00032_ArrayList集合的遍历

    1.通过集合遍历,得到集合中每个元素,这是集合中最常见的操作 2.集合的遍历与数组的遍历很像,都是通过索引的方式 public class ArrayListDemo02 { public stati ...

  10. 解决win7下pycharm移动文件出现Clear Read-Only status移动失败的问题

    问题描述: 将pycharm中的文件move到指定文件夹或者将其他文件拖动到pycharm指定文件夹下,会出现如下问题导致文件移动失败: 出现这个问题的原因及解决办法如下: 第一种,pycharm下建 ...