静态区间第K小(整体二分、主席树)
题目链接
题解
主席树入门题
但是这里给出整体二分解法
整体二分顾名思义是把所有操作放在一起二分
想想,如果求\([1-n]\)的第\(k\)小怎么二分求得?
我们可以二分答案\(k\), \(O(n)\)统计有多少个数小于等于\(k\)
如果对于每个询问都这么搞,肯定不行
我们可以发现,如果每次都搞一次,有许多算重复的地方
\(div(l, r, st, ed)\)表示\(k\)二分的区间\([l-r]\), 对应操作答案区间在\([st-ed]\)
(如果没看懂,先往下看。)
\(mid = (l+r)/2\)
对于每次的\(mid\), 我们把对\(k\)往左移还有贡献的 放在一起, 右移的放在一起,这样答案就在一个区间内
那么如何统计一段区间有多少个数比\(k\)大呢?
我们开一个树状数组,如果\(x\)位上的数大于\(k\),那么给\(x\)加上1
然后统计就是区间求和了
Code
#include<bits/stdc++.h>
#define LL long long
#define RG register
using namespace std;
const int N = 200010, INF = 1e9;
struct rec {
int op, x, y, z;
}q[N<<1], lq[N<<1], rq[N<<1];
int n, m, tot, c[N], ans[N];
#define lowbit(x) (x&(-x))
void add(int x, int v) {
while (x <= n) c[x] += v, x += lowbit(x);
return ;
}
int sum(int x) {
int res = 0;
while (x > 0) res += c[x], x -= lowbit(x);
return res;
}
int X[N], cnt;
inline int gi() {
RG int x = 0; RG char c = getchar(); bool f = 0;
while (c != '-' && (c < '0' || c > '9')) c = getchar();
if (c == '-') c = getchar(), f = 1;
while (c >= '0' && c <= '9') x = x*10+c-'0', c = getchar();
return f ? -x : x;
}
void div(int l, int r, int st, int ed) {
if (st > ed) return ;//[l~r]中没有答案
if (l == r) {
for (int i = st; i <= ed; i++)
if (q[i].op) ans[q[i].op] = l;//记录答案
return ;
}
int mid = (l + r) >> 1;
int lt = 0, rt = 0;
for (int i = st; i <= ed; i++) {
if (!q[i].op) {
if (q[i].y <= mid) add(q[i].x, 1), lq[++lt] = q[i];//k如果往左移,修改操作还有影响
else rq[++rt] = q[i];
}
else {
int res = sum(q[i].y) - sum(q[i].x-1);
if (res >= q[i].z) lq[++lt] = q[i];//已经满足至少第K大了,K还可以调小
else q[i].z -= res, /*把所有q[i].y<=mid的贡献减去,调大k时就不需要统计这些的贡献了*/rq[++rt] = q[i];
}
}
for (int i = st; i <= ed; i++)
if (!q[i].op && q[i].y <= mid) add(q[i].x, -1);//清除
for (int i = 1; i <= lt; i++) q[st+i-1] = lq[i];
for (int i = 1; i <= rt; i++) q[st+lt+i-1] = rq[i];
div(l, mid, st, st+lt-1);
div(mid+1, r, st+lt, ed);
return ;
}
int main() {
//freopen(".in", "r", stdin);
//freopen(".out", "w", stdout);
n = gi(); m = gi();
for (int i = 1; i <= n; i++) {
q[++tot].op = 0, q[tot].x = i, X[++cnt] = q[tot].y = gi();
}
sort(X+1, X+1+cnt); cnt = unique(X+1, X+cnt+1)-X-1;//离散化
for (int i = 1; i <= n; i++)
q[i].y = lower_bound(X+1, X+cnt+1, q[i].y)-X;
for (int i = 1; i <= m; i++) {
q[++tot].op = i; q[tot].x = gi();q[tot].y = gi();q[tot].z = gi();
}
div(1, n, 1, tot);
for (int i = 1; i <= m; i++)
printf("%d\n", X[ans[i]]);
return 0;
}
静态区间第K小(整体二分、主席树)的更多相关文章
- 静态区间第k小 - 整体二分
蒟蒻终于学会整体二分啦! 思路 实现 丑陋无比的代码 #include <bits/stdc++.h> using namespace std; const int N = 200005; ...
- 【XSY2720】区间第k小 整体二分 可持久化线段树
题目描述 给你你个序列,每次求区间第\(k\)小的数. 本题中,如果一个数在询问区间中出现了超过\(w\)次,那么就把这个数视为\(n\). 强制在线. \(n\leq 100000,a_i<n ...
- POJ2104 K-th Number —— 区间第k小 整体二分
题目链接:https://vjudge.net/problem/POJ-2104 K-th Number Time Limit: 20000MS Memory Limit: 65536K Tota ...
- Dynamic Rankings || 动态/静态区间第k小(主席树)
JYF大佬说,一星期要写很多篇博客才会有人看 但是我做题没有那么快啊QwQ Part1 写在前面 区间第K小问题一直是主席树经典题=w=今天的重点是动态区间第K小问题.静态问题要求查询一个区间内的第k ...
- 51nod 1175 区间第k大 整体二分
题意: 一个长度为N的整数序列,编号0 - N - 1.进行Q次查询,查询编号i至j的所有数中,第K大的数是多少. 分析: 仅仅就是一道整体二分的入门题而已,没听说过整体二分? 其实就是一个分治的函数 ...
- [xdoj1216]子树第k小(dfs序+主席树)
解题关键:dfs序将树映射到区间,然后主席树求区间第k小,为模板题. #pragma comment(linker, "/STACK:1024000000,1024000000") ...
- 区间第K小——可持久化线段树模板
概念 可持久化线段树又叫主席树,之所以叫主席树是因为这东西是fotile主席创建出来的. 可持久化数据结构思想,就是保留整个操作的历史,即,对一个线段树进行操作之后,保留访问操作前的线段树的能力. 最 ...
- [luogu3834]静态区间第k小【主席树】
传送门:https://www.luogu.org/problemnew/show/P3834 题目描述 如题,给定N个整数构成的序列,将对于指定的闭区间查询其区间内的第K小值. 分析 很多人都说是用 ...
- 主席树(可持久化线段树)静态区间第K小
传送门主席树 #include <bits/stdc++.h> #define int long long using namespace std; const int maxn=2e5+ ...
随机推荐
- nohup 无发后台运行
用nohup命令让Linux下程序永远在后台执行 [ 2006-5-13 22:31:54 | By: 牧云 ] Unix/Linux下一般想让某个程序在后台运行,很多都是使用 & 在 ...
- CURL以 POST 请求链接的方式 初始化一个cURL会话来获取一个网页
/** *POST URL */ function posturl($URL,$data) { $ch = curl_init(); // 创建一个新cURL资源 curl_setopt($ch,CU ...
- Hyperledger项目中使用的工具
Hyperledger作为一个众多IT厂商参与的项目,全球化的开源社区,其项目的组织形式.流程.工具,都值得借鉴.好工匠离不开好工具,我注意到Hyperledger项目中使用了大量的好工具,包括项目管 ...
- 学习PDO啦
通过查找资料对PDO有了一定的了解,PDO(PHP Data Object )为PHP数据对象,为PHP访问数据库提供了一个轻量级的借口,但PDO本生不能实现访问数据库的任何功能,只能通过数据库的PD ...
- IntelliJ IDEA——maven环境下整合SSM
SSM整合目录结构 开发环境:JDK1.8:apache-tomcat-7.0.52 : MySql5.7 开发工具:IntelliJ IDEA pom.xml <?xml version=&q ...
- CSS3 grayscale滤镜图片变黑白
1. 使整个页面的图片都变成灰色的,代码如下. html{ font-size: 100%; -webkit-text-size-adjust: none; -ms-text-s ...
- bootstrap导航菜单
<!DOCTYPE html><html lang="zh-cn"><head><meta charset="utf-8&quo ...
- 20145218PC平台逆向破解
20145218PC平台逆向破解 实践目标 本次实践的对象是一个名为pwn1的linux可执行文件. 该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串. 该程序同 ...
- 「BZOJ 1001」狼抓兔子
题目链接 luogu bzoj \(Solution\) 这个貌似没有什么好讲的吧,直接按照这个给的图建图就好了啊,没有什么脑子,但是几点要注意的: 建双向边啊. 要这么写,中间还要写一个\(whil ...
- 从程序员的角度深入理解MySQL
前言 今天我将站在程序员的角度以MySQL为例探索数据库的奥秘! 数据库基本原理 我对DB的理解 1.数据库的组成:存储 + 实例 不必多说,数据当然需要存储:存储了还不够,显然需要提供程序对存储 ...