Description

给定一个长度为 \(n\) 的序列, \(m\) 次操作静态查询区间第 \(k\) 大

Input

第一行是 \(n,m\)

下一行描述这个序列

下面 \(m\) 行描述操作

Output

每个查询输出一行一个数代表答案

Hint

\(1~\leq~n,~m~\leq~2~\times~10^5\)

值域为 \([-1e9,~1e9]\)

Solution

考虑整体二分。

将操作和序列全部离线,混在一起操作,在每层中,如果一个插入操作插入的数大于 mid,则压入右边的vector,否则压入左边的vector,这样即可保证在每一层整个序列的插入操作只被操作 \(1\) 次。用树状数组维护不大于 mid 的插入点,插入点个数不小于 \(k\) 的查询压入左侧,否则 \(k~-=~\text{压入点个数}\) ,压入右侧即可。

注意一个区间内没有操作的时候要剪枝,否则复杂度会加上值域。

总复杂度 \(O((n + m)~\log^2 m)\)

Code

  1. // luogu-judger-enable-o2
  2. #include <cstdio>
  3. #include <vector>
  4. #include <iostream>
  5. #ifdef ONLINE_JUDGE
  6. #define freopen(a, b, c)
  7. #endif
  8. typedef long long int ll;
  9. namespace IPT {
  10. const int L = 1000000;
  11. char buf[L], *front=buf, *end=buf;
  12. char GetChar() {
  13. if (front == end) {
  14. end = buf + fread(front = buf, 1, L, stdin);
  15. if (front == end) return -1;
  16. }
  17. return *(front++);
  18. }
  19. }
  20. template <typename T>
  21. inline void qr(T &x) {
  22. char ch = IPT::GetChar(), lst = ' ';
  23. while ((ch > '9') || (ch < '0')) lst = ch, ch=IPT::GetChar();
  24. while ((ch >= '0') && (ch <= '9')) x = (x << 1) + (x << 3) + (ch ^ 48), ch = IPT::GetChar();
  25. if (lst == '-') x = -x;
  26. }
  27. namespace OPT {
  28. char buf[120];
  29. }
  30. template <typename T>
  31. inline void qw(T x, const char aft, const bool pt) {
  32. if (x < 0) {x = -x, putchar('-');}
  33. int top=0;
  34. do {OPT::buf[++top] = static_cast<char>(x % 10 + '0');} while (x /= 10);
  35. while (top) putchar(OPT::buf[top--]);
  36. if (pt) putchar(aft);
  37. }
  38. const int maxn = 200010;
  39. const int INF = 1000000010;
  40. struct OP {
  41. int l, r, k, id;
  42. };
  43. std::vector<OP> Q;
  44. int n, m;
  45. int ans[maxn], tree[maxn];
  46. int lowbit(int);
  47. int query(int);
  48. void update(int, const int);
  49. void divide(int, int, std::vector<OP>&);
  50. int main() {
  51. freopen("1.in", "r", stdin);
  52. qr(n); qr(m);
  53. for (int i = 1, x; i <= n; ++i) {
  54. x = 0; qr(x); Q.push_back({-1, 0, x, i});
  55. }
  56. for (int i = 1, a, b, c; i <= m; ++i) {
  57. a = b = c = 0; qr(a); qr(b); qr(c);
  58. Q.push_back({a, b, c, i});
  59. }
  60. divide(-INF, INF, Q);
  61. for (int i = 1; i <= m; ++i) qw(ans[i], '\n', true);
  62. return 0;
  63. }
  64. void divide(int l, int r, std::vector<OP> &v) {
  65. if (!v.size()) return;
  66. if (l == r) {
  67. for (auto i : v) if (i.l != -1) ans[i.id] = l;
  68. return;
  69. }
  70. std::vector<OP>ldown, rdown;
  71. int mid = (l + r) >> 1;
  72. for (auto i : v) {
  73. if (i.l == -1) {
  74. if (i.k <= mid) {
  75. update(i.id, 1);
  76. ldown.push_back(i);
  77. } else rdown.push_back(i);
  78. }
  79. }
  80. for (auto i : v) {
  81. if (i.l != -1) {
  82. int k = query(i.r) - query(i.l - 1);
  83. if ((k) >= i.k) ldown.push_back(i);
  84. else {
  85. i.k -= k; rdown.push_back(i);
  86. }
  87. }
  88. }
  89. for (auto i : ldown) {
  90. if (i.l == -1) update(i.id, -1);
  91. }
  92. divide(l, mid, ldown);
  93. divide(mid + 1, r, rdown);
  94. }
  95. inline int lowbit(int x) {return x & -x;}
  96. void update(int x, const int v) {
  97. while (x <= n) {
  98. tree[x] += v;
  99. x += lowbit(x);
  100. }
  101. }
  102. int query(int x) {
  103. int _ret = 0;
  104. while (x) {
  105. _ret += tree[x];
  106. x -= lowbit(x);
  107. }
  108. return _ret;
  109. }

【整体二分】【P3834】 【模板】可持久化线段树 1(主席树)的更多相关文章

  1. 洛谷P3834 [模板]可持久化线段树1(主席树) [主席树]

    题目传送门 可持久化线段树1(主席树) 题目背景 这是个非常经典的主席树入门题——静态区间第K小 数据已经过加强,请使用主席树.同时请注意常数优化 题目描述 如题,给定N个正整数构成的序列,将对于指定 ...

  2. P3919 【模板】可持久化数组 -初步探究主席树

    本篇blog主要是给自己(大家)看的. 感谢longlongzhu123奆佬(此人初二LCT)的指点,使本蒟蒻可以快速开始主席树入门. what is 主席树? $        $主席树这个名字只不 ...

  3. 归并树 划分树 可持久化线段树(主席树) 入门题 hdu 2665

    如果题目给出1e5的数据范围,,以前只会用n*log(n)的方法去想 今天学了一下两三种n*n*log(n)的数据结构 他们就是大名鼎鼎的 归并树 划分树 主席树,,,, 首先来说两个问题,,区间第k ...

  4. POJ 2104 K-th Number(分桶,线段树,主席树)

    一道比较经典的数据结构题.可以用多种方式来做. 一,分桶法(平方分解). 根据数字x的大小和区间内不大于x的数字数量cnt的单调性,可知第k大数kth对应的cnt应该满足cnt≥k, 且kth是满足条 ...

  5. 【题解】BZOJ3489 A Hard RMQ problem(主席树套主席树)

    [题解]A simple RMQ problem 占坑,免得咕咕咕了,争取在2h内写出代码 upd:由于博主太菜而且硬是要用指针写两个主席树,所以延后2hQAQ upd:由于博主太菜而且太懒所以他决定 ...

  6. poj 2104 K-th Number 划分树,主席树讲解

    K-th Number Input The first line of the input file contains n --- the size of the array, and m --- t ...

  7. 【BZOJ4771】七彩树(主席树)

    [BZOJ4771]七彩树(主席树) 题面 BZOJ 题解 如果没有深度限制,每次只询问子树内的颜色个数,除了树套树\(dfs\)序加前驱或者后继强行二维数点之外,还有这样一种做法: 把所有相同颜色的 ...

  8. 洛谷P3248 树 [HNOI2016] 主席树+倍增+分治

    正解:主席树+倍增+分治 解题报告: 传送门! 首先看到这题会想到之前考过的这题 但是那题其实简单一些,,,因为那题只要用个分治+预处理就好,只是有点儿思维难度而已 这题就不一样,因为它说了是按照原树 ...

  9. BZOJ_2588_Spoj 10628. Count on a tree_树剖+主席树

    BZOJ_2588_Spoj 10628. Count on a tree_树剖+主席树 题意: 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastan ...

  10. POJ 2761 Feed the dogs(平衡树or划分树or主席树)

    Description Wind loves pretty dogs very much, and she has n pet dogs. So Jiajia has to feed the dogs ...

随机推荐

  1. java中重要的多线程工具类

    前言 之前学多线程的时候没有学习线程的同步工具类(辅助类).ps:当时觉得暂时用不上,认为是挺高深的知识点就没去管了.. 在前几天,朋友发了一篇比较好的Semaphore文章过来,然后在浏览博客的时候 ...

  2. js备忘录1

    新建对象 赋值和取值操作 var book={ topic:"JavaScript", fat: true }; book.topic  通过点访问 book["fat& ...

  3. 在Web Page中包含PHP代码

    PHP代码可以出现在Web Page的任何位置,甚至在HTML的标签里面也可以.有4中方式在Web Page中包含PHP代码: 使用<?php ... ?>标签 <!doctype ...

  4. delphi 图像处理 图像放大缩小

    procedure TDR_QM_ZP_Form.btn_FDClick(Sender: TObject); //图像放大 begin my_int1 := Trunc( my_int1 * 1.1) ...

  5. Ubuntu登录界面添加root用户登录选项

    1.普通用户登录系统并打开终端 配置root密码 $sudo passwd 切换至root用户 $su root 输入密码 修改以下配置文件 $nano /usr/share/lightdm/ligh ...

  6. Java 单生产者消费者问题

    package com.cwcec.test; class Resource { private int count = 0; private boolean flag = false; public ...

  7. AWS上的实例无法ping通的解决方案

    首先Ping只是向服务器发送ICMP的数据包,如果在服务器的防火墙没有允许ICMP协议的数据包的话,那么即使服务器正常运行,那也是ping不同的. 对于亚马逊云服务器,首先我们要确保实例绑定的安全组允 ...

  8. CAS (1) —— Mac下配置CAS到Tomcat(服务端)

    CAS (1) -- Mac下配置CAS到Tomcat(服务端) tomcat版本: tomcat-8.0.29 jdk版本: jdk1.8.0_65 cas版本: cas4.1.2 cas-clie ...

  9. beta发布的评论

    1. 组名:飞天小女警 项目名:礼物挑选小工具 评价:对于我们学生来说,选礼物小工具相对来说新颖,小组添加了前十名热门礼物的推荐.发布到服务器上了,未来也有很多选择的空间可以做成礼物挑选手机app,也 ...

  10. exFAT移动硬盘写保护怎么去掉

    cmd命令提示符下运行chkdsk命令: 比如在E盘,则输入的命令如下: E:(冒号不可少,输入后回车) CHKDSK /F /X  (回车) 等命令执行完了,即可去掉exFAT移动硬盘写的保护.