带修主席树的模板,因为状态不好所以敲了很长时间,不过写完感觉能更好地理解主席树了。

核心其实就是树状数组套主席树,维护方法不再是以前的那种一步一修改,而是对于树状数组上的每一个点建立一棵权值线段树,然后一点一点地维护。这样就从朴素修改后缀所需要的每次\(O(NlogN)\)的复杂度,变成了修改\(log\)棵树所需要的\(O(Nlog^2N)\)。

几个注意事项:

  1. 本题卡常。请使用离散化后的权值进行建树。

  2. 本题卡常。不要用\(cin\)。

  3. 因为是权值线段树,所以要先删除再添加。

  4. 二分的时候也要带上全家桶(\(lowbit\)对应位)一起修改鸭~

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. const int N = 100010;
  4. int INF = 1000000010;
  5. int tot, rt[N];
  6. int n, m, arr[N];
  7. #define mid ((l + r) >> 1)
  8. #define lowbit(x) (x & -x)
  9. struct Segment_Tree {
  10. struct Segment_Node {
  11. int ls, rs, sz;
  12. }t[N << 9];
  13. Segment_Tree () {t[0].sz = 0;}
  14. void modify (int &v, int l, int r, int w, int del) {
  15. if (v == 0) v = ++tot;
  16. t[v].sz += del;
  17. if (l != r) {
  18. if (w <= mid) {
  19. modify (t[v].ls, l, mid + 0, w, del);
  20. } else {
  21. modify (t[v].rs, mid + 1, r, w, del);
  22. }
  23. }
  24. }
  25. }seg;
  26. int cnt, sep[N << 1];
  27. int _sep (int w) {
  28. return lower_bound (sep + 1, sep + 1 + cnt, w) - sep;
  29. }
  30. void change (int pos, int val) {
  31. for (int i = pos; i <= n; i += lowbit (i)) {
  32. seg.modify (rt[i], 0, INF, _sep (arr[pos]), -1);
  33. }
  34. arr[pos] = sep[val];
  35. for (int i = pos; i <= n; i += lowbit (i)) {
  36. seg.modify (rt[i], 0, INF, _sep (arr[pos]), +1);
  37. }
  38. }
  39. int query (int u, int v, int k) {
  40. static int _u[30], _v[30];
  41. // u 到 v 区间第 k 小
  42. int l = 0, r = INF;
  43. _u[0] = _v[0] = 0;
  44. for (int i = u; i != 0; i -= lowbit (i)) _u[++_u[0]] = rt[i];
  45. for (int i = v; i != 0; i -= lowbit (i)) _v[++_v[0]] = rt[i];
  46. while (l < r) {
  47. int lch = 0;
  48. for (int i = 1; i <= _u[0]; ++i) lch -= seg.t[seg.t[_u[i]].ls].sz;
  49. for (int i = 1; i <= _v[0]; ++i) lch += seg.t[seg.t[_v[i]].ls].sz;
  50. if (k <= lch) {
  51. for (int i = 1; i <= _u[0]; ++i) _u[i] = seg.t[_u[i]].ls;
  52. for (int i = 1; i <= _v[0]; ++i) _v[i] = seg.t[_v[i]].ls;
  53. r = mid;
  54. } else {
  55. for (int i = 1; i <= _u[0]; ++i) _u[i] = seg.t[_u[i]].rs;
  56. for (int i = 1; i <= _v[0]; ++i) _v[i] = seg.t[_v[i]].rs;
  57. l = mid + 1;
  58. k -= lch;
  59. }
  60. }
  61. return r;
  62. }
  63. struct Query {
  64. int type, l, r, k, p, w;
  65. }q[N];
  66. int main () {
  67. // cin >> n >> m;
  68. scanf ("%d %d", &n, &m);
  69. for (int i = 1; i <= n; ++i) {
  70. scanf ("%d", &arr[i]);
  71. sep[++cnt] = arr[i];
  72. }
  73. for (int i = 1; i <= m; ++i) {
  74. static char opt[10];
  75. scanf ("%s", opt);
  76. if (opt[0] == 'Q') {
  77. q[i].type = 0;
  78. scanf ("%d %d %d", &q[i].l, &q[i].r, &q[i].k);
  79. } else {
  80. q[i].type = 1;
  81. scanf ("%d %d", &q[i].p, &q[i].w);
  82. sep[++cnt] = q[i].w;
  83. }
  84. }
  85. sort (sep + 1, sep + 1 + cnt);
  86. cnt = unique (sep + 1, sep + 1 + cnt) - sep - 1; INF = cnt;
  87. for (int i = 1; i <= n; ++i) {
  88. for (int j = i; j <= n; j += lowbit (j)) {
  89. seg.modify (rt[j], 0, INF, _sep (arr[i]), +1);
  90. }
  91. }
  92. for (int i = 1; i <= m; ++i) {
  93. if (q[i].type == 0) {
  94. printf ("%d\n", sep[query (q[i].l - 1, q[i].r, q[i].k)]);
  95. } else {
  96. change (q[i].p, _sep (q[i].w));
  97. }
  98. }
  99. }

Luogu P2617 Dynamic Rankings的更多相关文章

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

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

  2. luogu P2617 Dynamic Rankings(主席树)

    嘟嘟嘟 一句话题意:带修改区间第\(k\)小. 不修改都会,主席树板子.但是有修改就要比较深入的理解主席树了. 众所周知,主席树中以\(i\)为根的线段树维护的是\([1, i]\)这个前缀的权值,因 ...

  3. luogu P2617 Dynamic Rankings(分块,n <= 1e4)

    嘟嘟嘟 带修改区间第k大. 然而某谷把数据扩大到了1e5,所以用分块现在只能得50分. 分块怎么做呢?很暴力的. 基本思想还是块内有序,块外暴力统计. 对于修改,直接重排修改的数所在块,时间复杂度O( ...

  4. Luogu P2617 Dynamic Rankings(整体二分)

    题目 动态区间第K小模板题. 一个非常可行的办法是BIT套动态开点权值SegTree,但是它跑的实在太慢了. 然后由于这题并没有强制在线,所以我们可以使用整体二分来吊打树套树. 当然如果强制在线的话就 ...

  5. LUOGU P2617 Dynamic Rankings(树状数组套主席树)

    传送门 解题思路 动态区间第\(k\)大,树状数组套主席树模板.树状数组的每个位置的意思的是每棵主席树的根,维护的是一个前缀和.然后询问的时候\(log\)个点一起做前缀和,一起移动.时空复杂度\(O ...

  6. [luogu P2617] Dynamic Rankings 带修主席树

    带修改的主席树,其实这种,已经不能算作主席树了,因为这个没有维护可持久化的... 主席树直接带修改的话,由于这种数据结构是可持久化的,那么要相应改动,这个节点以后所有的主席树,这样单次修改,就达到n* ...

  7. P2617 Dynamic Rankings(树状数组套主席树)

    P2617 Dynamic Rankings 单点修改,区间查询第k大 当然是无脑树套树了~ 树状数组套主席树就好辣 #include<iostream> #include<cstd ...

  8. 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 ...

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

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

随机推荐

  1. LVS (Linux Virtual Server) 负载均衡

    [大型网站技术实践]初级篇:借助LVS+Keepalived实现负载均衡   一.负载均衡:必不可少的基础手段 1.1 找更多的牛来拉车吧 当前大多数的互联网系统都使用了服务器集群技术,集群即将相同服 ...

  2. 一、Java多人博客系统-开篇

    作为一个程序员,工作之外的不断学习是必须的.这个项目是我个人课外学习和练手的项目.最开始是一个个人网站.当时发现京东云可以免费部署网站的,就立即写了一个网站,当时就使用jsp技术,可以实现发布博客.评 ...

  3. 【CPU】理解CPU

    CPU,全称Central Processing Unit,即中央处理器. 何为CPU? 计算机必须能够自动地从主存中取出一条条指令执行,专门来执行指令的就是CPU. 一.指令的执行过程 为了理解CP ...

  4. iptables防火墙的原理及应用

    简介 (netfilter, 位于Linux内核中的包过滤功能体系  ,称为Linux防火墙的“内核态”) iptables防火墙工作在网络层,针对TCP/IP数据包实施过滤和限制,iptables防 ...

  5. python 模块之-shelve

    shelve模块比pickle模块简单,只有一个open函数,返回类似字典的对象,可读可写;key必须为字符串,而值可以是python所支持的数据类型 import shelve f = shelve ...

  6. 简单探究Android平台下' if ' 语句条件判断耗时情况

    2017年6月13日 前言 前几日在改Bug时看到好多调试时用的日志语句都被一个日志开关控制着它的执行权.形如: if(Constants.LOG_TAG){ Log.d(TAG, "Ini ...

  7. 数据结构与算法(Python)

    一.数据结构与算法概述 数据结构与算法的定义 我们把现实中大量而且非常复杂的问题以特定的数据类型(个体)和特定的存储结构(个体的关系)保存到相应的主存储器(内存)中,以及在此基础上为实现某个功能而执行 ...

  8. Django ORM模型

    Object Relational Mapping(ORM) 一,ORM介绍 1, ORM概念 对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象 ...

  9. Git初始化及配置

    >>>>Git简介 >>>>官网下载Git >>>>安装,一路next 安装成功后,鼠标右键里就有Git bash here和G ...

  10. CF527E Data Center Drama(构造+欧拉回路)

    题目链接 大意: 给你一个无向图. 要求加最少的边,然后给这些无向图的边定向,使得每一个点的出入度都是偶数. 输出定向后的边数和边集. n<=10^5 m<=2*10^5 很巧妙的构造题- ...