【笔记】主席树
挖坑,然后在这里种一棵主席树(
看了代码就很好理解了,对于单点操作只会使 logN 个节点产生变化,这样我们更新版本时,每次往下递归时都开一个新节点复制原来的信息就行了
查询的话从对应版本号的 rt[] 走
至于怎么用...嗯...
模板,静态查询区间第 K 小,权值线段树做差
原始版本的编号是 0 ,原始版本为空树
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN = 200005;
const int inf = 1e9+1;
int N, M, A[MAXN], rt[MAXN];
struct segmentTree {
#define lson ls[x]
#define rson rs[x]
int ls[MAXN<<5], rs[MAXN<<5], cnt[MAXN<<5], tot;
segmentTree() {
tot = 0;
memset(ls, 0, sizeof(ls));
memset(rs, 0, sizeof(rs));
memset(cnt, 0, sizeof(cnt));
}
void pushup(int x) { cnt[x] = cnt[lson] + cnt[rson]; }
void update(int &x, int pre, int l, int r, int p) { // cnt[p]++
x = ++tot, ls[x] = ls[pre], rs[x] = rs[pre], cnt[x] = cnt[pre];
if (l==r) cnt[x]++;
else {
int mid = (l + r) >> 1;
if (mid>=p) update(lson, ls[pre], l, mid, p);
if (mid< p) update(rson, rs[pre], mid+1, r, p);
pushup(x);
}
}
int query(int u, int v, int l, int r, int k) {
if (l==r) return l;
else {
int mid = (l + r) >> 1, sum = cnt[ls[v]] - cnt[ls[u]];
if (sum>=k) return query(ls[u], ls[v], l, mid, k);
else return query(rs[u], rs[v], mid+1, r, k-sum);
}
}
} ST;
int read()
{
register int o = 0, oo = 0;
register char c = getchar();
while (c< '0' || c> '9') o |= c=='-', c = getchar();
while (c>='0' && c<='9') o = (o<<3)+(o<<1)+(c&15), c = getchar();
return oo ? -o : o;
}
int main()
{
N = read(), M = read();
for (int i=1; i<=N; i++) A[i] = read();
for (int i=1; i<=N; i++) ST.update(rt[i], rt[i-1], -inf, inf, A[i]);
for (; M; M--) {
int l = read(), r = read(), k = read();
printf("%d\n", ST.query(rt[l-1], rt[r], -inf, inf, k));
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 上周热点回顾(3.3-3.9)