【整体二分】【P3834】 【模板】可持久化线段树 1(主席树)
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
// luogu-judger-enable-o2
#include <cstdio>
#include <vector>
#include <iostream>
#ifdef ONLINE_JUDGE
#define freopen(a, b, c)
#endif
typedef long long int ll;
namespace IPT {
const int L = 1000000;
char buf[L], *front=buf, *end=buf;
char GetChar() {
if (front == end) {
end = buf + fread(front = buf, 1, L, stdin);
if (front == end) return -1;
}
return *(front++);
}
}
template <typename T>
inline void qr(T &x) {
char ch = IPT::GetChar(), lst = ' ';
while ((ch > '9') || (ch < '0')) lst = ch, ch=IPT::GetChar();
while ((ch >= '0') && (ch <= '9')) x = (x << 1) + (x << 3) + (ch ^ 48), ch = IPT::GetChar();
if (lst == '-') x = -x;
}
namespace OPT {
char buf[120];
}
template <typename T>
inline void qw(T x, const char aft, const bool pt) {
if (x < 0) {x = -x, putchar('-');}
int top=0;
do {OPT::buf[++top] = static_cast<char>(x % 10 + '0');} while (x /= 10);
while (top) putchar(OPT::buf[top--]);
if (pt) putchar(aft);
}
const int maxn = 200010;
const int INF = 1000000010;
struct OP {
int l, r, k, id;
};
std::vector<OP> Q;
int n, m;
int ans[maxn], tree[maxn];
int lowbit(int);
int query(int);
void update(int, const int);
void divide(int, int, std::vector<OP>&);
int main() {
freopen("1.in", "r", stdin);
qr(n); qr(m);
for (int i = 1, x; i <= n; ++i) {
x = 0; qr(x); Q.push_back({-1, 0, x, i});
}
for (int i = 1, a, b, c; i <= m; ++i) {
a = b = c = 0; qr(a); qr(b); qr(c);
Q.push_back({a, b, c, i});
}
divide(-INF, INF, Q);
for (int i = 1; i <= m; ++i) qw(ans[i], '\n', true);
return 0;
}
void divide(int l, int r, std::vector<OP> &v) {
if (!v.size()) return;
if (l == r) {
for (auto i : v) if (i.l != -1) ans[i.id] = l;
return;
}
std::vector<OP>ldown, rdown;
int mid = (l + r) >> 1;
for (auto i : v) {
if (i.l == -1) {
if (i.k <= mid) {
update(i.id, 1);
ldown.push_back(i);
} else rdown.push_back(i);
}
}
for (auto i : v) {
if (i.l != -1) {
int k = query(i.r) - query(i.l - 1);
if ((k) >= i.k) ldown.push_back(i);
else {
i.k -= k; rdown.push_back(i);
}
}
}
for (auto i : ldown) {
if (i.l == -1) update(i.id, -1);
}
divide(l, mid, ldown);
divide(mid + 1, r, rdown);
}
inline int lowbit(int x) {return x & -x;}
void update(int x, const int v) {
while (x <= n) {
tree[x] += v;
x += lowbit(x);
}
}
int query(int x) {
int _ret = 0;
while (x) {
_ret += tree[x];
x -= lowbit(x);
}
return _ret;
}
【整体二分】【P3834】 【模板】可持久化线段树 1(主席树)的更多相关文章
- 洛谷P3834 [模板]可持久化线段树1(主席树) [主席树]
题目传送门 可持久化线段树1(主席树) 题目背景 这是个非常经典的主席树入门题——静态区间第K小 数据已经过加强,请使用主席树.同时请注意常数优化 题目描述 如题,给定N个正整数构成的序列,将对于指定 ...
- P3919 【模板】可持久化数组 -初步探究主席树
本篇blog主要是给自己(大家)看的. 感谢longlongzhu123奆佬(此人初二LCT)的指点,使本蒟蒻可以快速开始主席树入门. what is 主席树? $ $主席树这个名字只不 ...
- 归并树 划分树 可持久化线段树(主席树) 入门题 hdu 2665
如果题目给出1e5的数据范围,,以前只会用n*log(n)的方法去想 今天学了一下两三种n*n*log(n)的数据结构 他们就是大名鼎鼎的 归并树 划分树 主席树,,,, 首先来说两个问题,,区间第k ...
- POJ 2104 K-th Number(分桶,线段树,主席树)
一道比较经典的数据结构题.可以用多种方式来做. 一,分桶法(平方分解). 根据数字x的大小和区间内不大于x的数字数量cnt的单调性,可知第k大数kth对应的cnt应该满足cnt≥k, 且kth是满足条 ...
- 【题解】BZOJ3489 A Hard RMQ problem(主席树套主席树)
[题解]A simple RMQ problem 占坑,免得咕咕咕了,争取在2h内写出代码 upd:由于博主太菜而且硬是要用指针写两个主席树,所以延后2hQAQ upd:由于博主太菜而且太懒所以他决定 ...
- 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 ...
- 【BZOJ4771】七彩树(主席树)
[BZOJ4771]七彩树(主席树) 题面 BZOJ 题解 如果没有深度限制,每次只询问子树内的颜色个数,除了树套树\(dfs\)序加前驱或者后继强行二维数点之外,还有这样一种做法: 把所有相同颜色的 ...
- 洛谷P3248 树 [HNOI2016] 主席树+倍增+分治
正解:主席树+倍增+分治 解题报告: 传送门! 首先看到这题会想到之前考过的这题 但是那题其实简单一些,,,因为那题只要用个分治+预处理就好,只是有点儿思维难度而已 这题就不一样,因为它说了是按照原树 ...
- BZOJ_2588_Spoj 10628. Count on a tree_树剖+主席树
BZOJ_2588_Spoj 10628. Count on a tree_树剖+主席树 题意: 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastan ...
- 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 ...
随机推荐
- http跳转https方法:百度云如何让http自动跳转到https【免费SSL证书使用FAQ】
之前的一篇文章已经给大家提供了免费SSL证书的申请方法,这一篇文章是告诉大家在使用免费的SSL证书时可能会遇到的问题[怎么让http自动跳转到https以及http与https同时使用]的解决方法. ...
- Nginx笔记(一):安装
Nginx在安装前需要先安装其所依赖的类库,所以需先行安装好之后再进行Nginx安装. Nginx依赖以下模块: l gzip模块需要 zlib 库 l rewrite模块需要 pcre 库 l ...
- final发布--PSP Daily软件功能书(最终版)
一.开发背景 你在完成了一周的软件工程作业后,需要提交一个PSP图表,里面有4项,如下所示: 1.本周PSP表格,包含每项任务的开始.中断.结束.最终时间,格式如下: 2.本周进度条,包含从开始到现在 ...
- 20162314 Experiment 2 - Tree
Experiment report of Besti course:<Program Design & Data Structures> Class: 1623 Student N ...
- Javascript实现大整数加法
记得之前面试还被问到过用两个字符串实现两个大整数相加,当时还特别好奇好好的整数相加,为什么要用字符串去执行.哈哈,感觉当时自己还是很无知的,面试官肯定特别的无奈.今天在刷算法的时候,无意中看到了为什么 ...
- 从高版本JDK换成低版本JDK报错Unsupported major.minor version 52.0的解决方案
从高版本JDK换成低版本JDK报错Unsupported major.minor version 52.0 java.lang.UnsupportedClassVersionError: PR/Sor ...
- 1001 A+B
代码链接 PDF链接 首先要说的是这道题的难点是如何把数字输出加入逗号,毕竟数据范围并没有超过Long.当然这个难点也不是问题,将数字转为字符串,C中就有这样的函数,然后再用 %3==0 这样来控制输 ...
- 作业6 团队项目之(开始第一个Sprint)
一.模仿并超越--类似应用. 五个app:1.四则运算小学堂(500-999次下载 3.57M) 2.小学生算术练习(9000+次下载 232K) 3.小学生加减题生成练习工具(2万-3万次下载 1. ...
- CS学习
作者:匿名用户链接:https://www.zhihu.com/question/27368268/answer/36464143来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注 ...
- C++编译与链接(0)-.h与.cpp中的定义与声明
C++中有的东西需要放在可以在.h文件中定义,有的东西则必须放在.cpp文件中定义,有的东西在不同的cpp文件中的名字可以一样,而有的则不能一样 那么究竟哪些东西可在头文件中定义,声明,哪些东西又必须 ...