当前位置: 首页 > news >正文

蜜汁整体二分——区间 kth

板子题(或许?):

link,点击这里喵。
小声:第一次学整体二分,有误请见谅。

题意:可持久化线段树 2——区间 kth.

如题,给定 nnn 个整数构成的序列 aaa,将对于指定的闭区间 [l,r][l, r][l,r] 查询其区间内的第 kkk 小值。

解法:

梦幻:如果我们能够维护一个数组 cnt[i][j]cnt[i][j]cnt[i][j],表示下标小于 iii,值小于 jjj 的数的个数就好了啊。
这样只需要二分 jjj 就能的出来了。
形式化的:
cnt[i][j]=∑e=in[ae<j]cnt[i][j]=\sum_{e=i}^n [a_e<j] cnt[i][j]=e=in[ae<j]
可这,空间炸了,时间也炸了。

思考一下权值线段树套区间和线段树的套路,发现是完全可行的,外层维护值域,内层维护下标。

思考一下权值线段树的作用,发现其仅仅是执行一个二分值域的操作,这非常类似于二分。

由于是离线的,我们完全可以把外层的权值线段树过掉!具体的,我们像权值线段树那样在每一个值域区间只维护那个值域区间内的点,如:

void dfs(int low, int high) {}

lowlowlow 维护最低值域,highhighhigh 维护最高值域,在这一层中,我们维护的点 a.v∈[low,high)a.v \in [low,high)a.v[low,high)

同时,我们也应当像权值线段树那样支持询问,模仿其思路,从上往下将询问分配到每一个区间,很像平衡树 rank→valrank \to valrankval 操作。

具体的,将他们两个合并在一个数组中就好了。

代码 time ~

#include <bits/stdc++.h>
using namespace std;#define inf 0x3f3f3f3f
typedef long long lnt;struct my_stream {int x;operator lnt() {scanf("%d", &x);return x;}
} __rp_read;
#define input() __rp_readconst int N = 1e6 + 20;#define lowbit(x) ((x) & -(x))
struct tray {const static int ys = 10;int g[N];void update(int b, int k) {b += ys;while (b < N) g[b] += k, b += lowbit(b);}int query(int b) {b += ys;int tp = 0;while (b) tp += g[b], b -= lowbit(b);return tp;}
} t;struct DQ {int id, x, y, k; // when id == 0, x means position, y means value
} d[N], tp[N];       // when id == 1, [x, y) means [l, r)int ans[N];void dfs(int low, int high, int bg, int ed) { // logVif (bg == ed) return;if (low == high - 1) {for (int i = bg; i < ed; ++i) //if (d[i].id != -1)        //ans[d[i].id] = low;return;}int mid = (low + high) >> 1, lp = bg, rp = ed;for (int i = bg; i < ed; ++i) {if (d[i].id != -1) continue;if (d[i].y < mid) tp[lp++] = d[i], t.update(d[i].x, 1);else if (d[i].id == -1) tp[--rp] = d[i];}for (int i = bg; i < ed; ++i) {if (d[i].id == -1) continue;int cnt = t.query(d[i].y - 1) - t.query(d[i].x - 1);if (d[i].k <= cnt) tp[lp++] = d[i];else tp[--rp] = d[i], tp[rp].k -= cnt;}for (int i = bg; i < lp; ++i) // clean BITif (tp[i].id == -1)       //t.update(tp[i].x, -1);copy(tp + bg, tp + ed, d + bg);dfs(low, mid, bg, lp);dfs(mid, high, lp, ed);
}int n, m;int main() { //n = input(), m = input();int top = 0;for (int i = 0; i < n; ++i) {d[top++] = {-1, i, input(), 0};}for (int i = 0; i < m; ++i) {int l = input(), r = input(), k = input();d[top++] = {i, l - 1, r, k};}dfs(0, inf, 0, n + m);for (int i = 0; i < m; ++i) {printf("%d\n", ans[i]);}return 0;
}
http://www.lryc.cn/news/610148.html

相关文章:

  • Next.js 中的文件路由:工作原理
  • 秋招笔记-8.4
  • 软件需求关闭前的质量评估标准是什么
  • Java项目:基于SSM框架实现的商铺租赁管理系统【ssm+B/S架构+源码+数据库+毕业论文+开题报告+任务书+远程部署】
  • 优化 Unity ConstantForce2D 性能的简单方法【资料】
  • 2025年08月04日Github流行趋势
  • 无偿分享120套开源数据可视化大屏H5模板
  • WSL安装Ubuntu与Docker环境,比VMware香
  • Flutter 对 Windows 不同版本的支持及 flutter_tts 兼容性指南
  • 离线Docker项目移植全攻略
  • Oracle 在线重定义
  • [GYCTF2020]FlaskApp
  • 【编程实践】点云曲率计算与可视化
  • 八股——Kafka相关
  • 【Pytorch✨】LSTM04 l理解长期记忆和短期记忆
  • 第12届蓝桥杯Scratch_选拔赛_初级组_真题2020年8月23日
  • 神经网络---非线性激活
  • C++进阶-封装红黑树模拟实现map和set(难度较高)
  • 李沐写作笔记
  • 嵌入式 C 语言入门:函数指针基础笔记 —— 从计算器优化到指针本质
  • SurferCloud vs LightNode 海外云服务商详细对比
  • 【无标题】标准 I/O 中的一些函数,按功能分类说明其用法和特点
  • [特殊字符] 50 天 50 个项目 — 完结篇
  • 【Docker安装】Ubuntu 24.04.2 LTS系统下安装Docker环境——指定APT源安装方式
  • 基于MobileNet卷积神经网络和Xception神经网络算法的人脸表情识别系统的设计与实现
  • C语言的控制语句
  • 每日一leetcode:移动零
  • 【Java】HashMap线程安全吗?
  • allegro建库--1
  • 【云馨AI-大模型】2025年8月第一周AI浪潮席卷全球:创新与政策双轮驱动