权值线段树
预备知识
学习权值线段树的预备知识,就是线段树,如果没有学过线段树,推荐先看完线段树,再回来看本文章
权值线段树
- 顾名思义,权值线段树是一颗线段树,但是又和普通的线段树不一样
- 线段树:每个节点用来维护一个区间的最大值或者总和,等等
- 权值线段树:与桶排序具有一定的相似性,每个节点相当于一个桶,用来表示一个区间的数出现的次数
相关问题
- 根据定义可以知道,我们可以用它快速计算一段区间的数的出现次数,或者是维护
- 当然他还有一个极其有用的功能,快速查找区间的第k大值或第k小值
- 这边的节点,与桶排序中的桶极其相似
相关操作
添加
- 和普通线段树类似,递归到叶子节点时给f[v]+=1
- 以下代码要添加的数是x,也就是x出现的次数+1;
void add(int l, int r, int v, int x)
{
if (l == r) f[v]++;
else
{
int mid = (l + r) / 2;
if (x <= mid) add(l, mid, v * 2, x);
else add(mid + 1, r, v * 2 + 1, x);
f[v] = f[v * 2] + f[v * 2 + 1];
}
}
查找一个数出现的次数
- 递归到叶节点是,f[v]即为所求值
- 下面为寻找数x的出现次数的代码
int find(int l, int r, int v, int x)
{
if (l == r) return f[v];
else
{
int mid = (l + r) / 2;
if (x <= mid) return find(l, mid, v * 2, x);
else return find(mid + 1, r, v * 2 + 1, x);
}
}
查询一段区间的数的出现次数
- 与线段树查询同理,不断的二分递归
- 以下的代码为查询区间[x,y]出现的次数
int find(int l, int r, int v, int x, int y)
{
if (l == x && r == y) return f[v];
else
{
int mid = (l + r) / 2;
if (y <= mid) return find(l, mid, v * 2, x, y);
else if (x > mid) return find(mid + 1, r, v * 2 + 1, x, y);
else return find(l, mid, v * 2, x, mid) + find(mid + 1, r, v * 2 + 1, mid + 1, y);
}
}
查询所有数的第k大值
- 还是先温故那句话:每个节点都是一个桶!这句话很重要
- 这是权值线段树的核心,思想如下:
- 到每个节点时,如果右子树的总和大于等于k,说明第k大值出现在右子树中,则递归进右子树;否则说明此时的第k大值在左子树中,则递归进左子树,注意:此时要将k的值减去右子树的总和。
- 为什么要减去?
- 假设我们要寻找的是第7大的值,右子树的总和为4,7−4=3,那么说明第7大值在左子树中是第3大值
- 最后递归到只有一个数时,那个数就是答案
int kth(int l, int r, int v, int k)
{
if (l == r) return l;
else
{
int mid = (l + r) / 2, s1 = f[v * 2], s2 = f[v * 2 + 1];
if (k <= s2) return kth(mid + 1, r, v * 2 + 1, k);
else return kth(l, mid, v * 2, k - s2);
}
}
总结
- 这些就是权值线段树的基本应用了
- 掌握这些之后你就可以进一步学习主席树了
我是一颗水灵灵的大白菜,
农民伯伯辛勤的耕种着我,
把我带到了菜市场
拿着喷头对着我浇水,
还一边说“好菜啊好菜”
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 理解Rust引用及其生命周期标识(下)
· 从二进制到误差:逐行拆解C语言浮点运算中的4008175468544之谜
· .NET制作智能桌面机器人:结合BotSharp智能体框架开发语音交互
· 软件产品开发中常见的10个问题及处理方法
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 2025成都.NET开发者Connect圆满结束
· 后端思维之高并发处理方案
· 千万级大表的优化技巧
· 在 VS Code 中,一键安装 MCP Server!
· 10年+ .NET Coder 心语 ── 继承的思维:从思维模式到架构设计的深度解析