- 前言
- 一、树状数组
- 1.功能介绍
- 2.例题 p3374
- 2.例题 逆序对p1908
- 二、st表
- 1.功能介绍
- 2.例题 p3865
- 三、bitset
- 1.功能介绍
- 2. 调试过程代码
树状数组可以认为是线段树的青春版
树状数组它有着丰富的功能,虽然不及线段树,但它代码简洁,思维清晰,速度也更快
它和st表有点相似,但功能相对更丰富些,树状数组仅靠一维数组便维护了整个区间具体为: c [ k ] = ∑ i = k − l o w b i t ( k ) + 1 k a [ i ] c[k]=\sum_{i=k-lowbit(k)+1}^{k}a[i] c[k]=i=k−lowbit(k)+1∑ka[i] l o w b i t ( x ) = x & ( − x ) lowbit(x)=x\&(-x) lowbit(x)=x&(−x)
它支持单点修改、区间修改(需要进行前缀变换)、单点查询、区间查询功能
树状数组的区间查询建立在前缀和的基础上,因此想让它求区间最值还得需要一定的变换,比较复杂,不推荐
int query(int x, int y) {
int ans = 0; // (log n) ^ 2
while (y >= x) {
ans = max(a[y], ans);
y--;
for (; y - lowbit(y) >= x; y -= lowbit(y)) ans = max(c[y], ans);
}
return ans;
}
所以它的应用场景一般就集中在数据查询,和逆序对上
此外,值得一提的是它可以与莫队结合求区间逆序对 贴一张图方便理解,图源 https://blog.csdn.net/bestsort/article/details/80796531
单点修改、区间求和 题目链接 洛谷p3374 代码如下:
#include
using namespace std;
const int maxn = 5e5 + 5;
int n, m;
int a[maxn], c[maxn];
int lowbit(int x) { return x & (-x); } // x 最后一位是 1 的位数
void update(int x, int val) { // c[k] = a[k-lowbit(i)+1] + ... + a[k]
for (int i = x; i
关注
打赏