我们将线段树套在树状数组上,查询前预处理出所有要一起移动的节点编号,并在查询过程中一起将这些节点移到左右子树上。
Code:

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<iostream>
  4. #include<algorithm>
  5. using namespace std;
  6. const int maxn = 6000000 + 5;
  7. int A[maxn], arr[maxn];
  8. int n, m, cnt;
  9. struct Queries
  10. {
  11. int c, l, r, k;
  12. Queries(int c = 0, int l = 0, int r = 0, int k = 0):c(c), l(l), r(r), k(k) {}
  13. }asks[maxn];
  14. struct Segment_Tree
  15. {
  16. int lson[maxn * 10], rson[maxn * 10], root[maxn], temp[2][200], count[2], sumv[maxn * 10];
  17. int cnt_Tree;
  18. inline int lowbit(int t)
  19. {
  20. return t & (-t);
  21. }
  22. void insert(int l, int r, int pos, int delta, int &o)
  23. {
  24. if(!o) o = ++cnt_Tree;
  25. sumv[o] += delta;
  26. if(l == r) return;
  27. int mid = (l + r) >> 1;
  28. if(pos <= mid)
  29. insert(l, mid, pos, delta, lson[o]);
  30. else
  31. insert(mid + 1, r, pos, delta, rson[o]);
  32. }
  33. inline void update(int pos, int val, int delta)
  34. {
  35. for(int i = pos;i <= n; i += lowbit(i))
  36. insert(1, n, val, delta, root[i]);
  37. }
  38. int query(int l, int r, int k)
  39. {
  40. if(l == r) return l;
  41. int sum = 0;
  42. for(int i = 1;i <= count[0]; ++i) sum += sumv[lson[temp[0][i]]];
  43. for(int i = 1;i <= count[1]; ++i) sum -= sumv[lson[temp[1][i]]];
  44. int mid = (l + r) >> 1;
  45. if(k <= sum) {
  46. for(int i = 1;i <= count[0]; ++i) temp[0][i] = lson[temp[0][i]];
  47. for(int i = 1;i <= count[1]; ++i) temp[1][i] = lson[temp[1][i]];
  48. return query(l, mid, k);
  49. }
  50. else
  51. {
  52. for(int i = 1;i <= count[0]; ++i) temp[0][i] = rson[temp[0][i]];
  53. for(int i = 1;i <= count[1]; ++i) temp[1][i] = rson[temp[1][i]];
  54. return query(mid + 1, r, k - sum);
  55. }
  56. }
  57. inline int Query(int l, int r, int k)
  58. {
  59. memset(temp, 0, sizeof(temp));
  60. count[0] = count[1] = 0;
  61. for(int i = r;i >= 1;i -= lowbit(i))
  62. temp[0][++count[0]] = root[i];
  63. for(int i = l - 1;i >= 1;i -= lowbit(i))
  64. temp[1][++count[1]] = root[i];
  65. return query(1, n, k);
  66. }
  67. }T;
  68. inline int get(int a)
  69. {
  70. return lower_bound(A + 1, A + 1 + cnt, a) - A;
  71. }
  72. int main()
  73. {
  74. scanf("%d%d",&n,&m);
  75. for(int i = 1;i <= n; ++i)
  76. {
  77. scanf("%d",&arr[i]);
  78. A[i] = arr[i];
  79. }
  80. cnt = n;
  81. for(int i = 1;i <= m; ++i)
  82. {
  83. char opt[3];
  84. scanf("%s",opt);
  85. if(opt[0] == 'Q')
  86. {
  87. int a, b, c;
  88. scanf("%d%d%d",&a,&b,&c);
  89. asks[i] = Queries(0, a, b, c);
  90. }
  91. if(opt[0] == 'C')
  92. {
  93. int a, b;
  94. scanf("%d%d",&a,&b);
  95. asks[i] = Queries(1, a, a, b);
  96. A[++cnt] = b;
  97. }
  98. }
  99. n = cnt;
  100. sort(A + 1, A + 1 + cnt);
  101. for(int i = 1;i <= n; ++i)
  102. {
  103. int cur_num = get(arr[i]);
  104. T.update(i, cur_num, 1);
  105. }
  106. for(int i = 1;i <= m; ++i)
  107. {
  108. if(asks[i].c)
  109. {
  110. int origin_num = get(arr[asks[i].l]);
  111. T.update(asks[i].l, origin_num, -1);
  112. int cur_num = get(asks[i].k);
  113. T.update(asks[i].l, cur_num, 1);
  114. arr[asks[i].l] = asks[i].k;
  115. }
  116. else printf("%d\n", A[T.Query(asks[i].l, asks[i].r, asks[i].k)]);
  117. }
  118. return 0;
  119. }

  

洛谷P2617 Dynamic Rankings 主席树 单点修改 区间查询第 K 大的更多相关文章

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

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

  2. luogu P2617 Dynamic Rankings && bzoj 1901 (带修改区间第k大)

    链接:https://www.luogu.org/problemnew/show/P2617 思路: 如果直接在主席树上修改的话,每次修改都会对后面所有的树造成影响,一次修改的复杂度就会变成 : n* ...

  3. 2018.07.01洛谷P2617 Dynamic Rankings(带修主席树)

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

  4. 洛谷 P2617 Dynamic Rankings || ZOJ - 2112

    写的让人看不懂,仅留作笔记 静态主席树,相当于前缀和套(可持久化方法构建的)值域线段树. 建树方法:记录前缀和的各位置的线段树的root.先建一个"第0棵线段树",是完整的(不需要 ...

  5. 洛谷 P2617 Dynamic Rankings 解题报告

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

  6. 洛谷P2617 Dynamic Rankings

    带修主席树模板题 主席树的单点修改就是把前缀和(大概)的形式改成用树状数组维护,每个树状数组的元素都套了一个主席树(相当于每个数组的元素root[i]都是主席树,且这个主席树维护了(i - lowbi ...

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

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

  8. 洛谷$P2617\ Dynamic\ Rankings$ 整体二分

    正解:整体二分 解题报告: 传送门$w$ 阿查询带修区间第$k$小不显然整体二分板子呗,,, 就考虑先按时间戳排序(,,,其实并不需要读入的时候就按着时间戳排的鸭$QwQ$ 每次二分出$mid$先把所 ...

  9. BZOJ1901 Zju2112 Dynamic Rankings 主席树

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1901 题意概括 给你一段序列(n个数),让你支持一些操作(共m次), 有两种操作,一种是询问区间第 ...

随机推荐

  1. P3图片导致iOS9.3以下崩溃问题

    如果你刚刚升级了Xcode8,而你的项目的Deployment Target是iOS 9.3以下,运行iOS8的时候过了几十秒后crash到main函数,出现EXC_BAD_ACCESS,或者崩溃到i ...

  2. hdu 2795 Billboard 【线段树】

    给出一个高为h,宽为w的广告板,有n张广告需要贴,从第一行开始贴,尽量靠左,输出每个广告最后贴在哪一行的 先一直想不通这样建树是为什么 后来看到一篇题解里面的一句话“直到找到一个满足条件的叶子节点” ...

  3. 使用C++部署Keras或TensorFlow模型

    本文介绍如何在C++环境中部署Keras或TensorFlow模型. 一.对于Keras, 第一步,使用Keras搭建.训练.保存模型. model.save('./your_keras_model. ...

  4. 工作流Activiti学习地址

    http://blog.csdn.net/xnf1991/article/details/52610277

  5. luogu P5290 [十二省联考2019]春节十二响 优先队列_启发式合并

    思维难度不大,在考上上写的启发式合并写错了,只拿了 60 pts,好难过QAQ 没什么太难的,在考场上想出链的部分分之后很容易就能想到正解.没错,就是非常短的启发式合并.注意一下,写的要漂亮一点,否则 ...

  6. Codeforces Round #499 (Div. 2) F. Mars rover_dfs_位运算

    题解: 首先,我们可以用 dfsdfsdfs 在 O(n)O(n)O(n) 的时间复杂度求出初始状态每个点的权值. 不难发现,一个叶子节点权值的取反会导致根节点的权值取反当且仅当从该叶子节点到根节点这 ...

  7. Pyhton学习——Day59

    参考博客: http://www.cnblogs.com/wupeiqi/articles/6144178.html Form 1. 验证 2. 生成HTML(保留上次输入内容) 3. 初始化默认是 ...

  8. scrollBot滚动条美化,niceScroll有滚动条错位得问题

    http://www.htmleaf.com/Demo/201706204585.html

  9. "随笔"列表 - 按时间先后顺序排列

    这是一个测试 linux采用scp命令拷贝文件到本地,拷贝本地文件到远程服务器 美化博客园 virtual box虚拟机在linux下设置共享文件夹 纯净版linux (debian)挂载Virtua ...

  10. jenkins 安装遇到的坑

                        最后启用安全的时候遇到一点坑,直接写了一个用户上去,没有勾选权限,然后在登录就说没有 overright/等,然后需要修改配置文件conf.xml 在主目录下. ...