树状数组模板(残缺)
作者:
再也不会
,
2021-10-04 19:50:23
,
所有人可见
,
阅读 340
注意单点修改和区间修改所对应的初始化方式有所不同
int tree[N];
//单点修改初始化
for(int i=1;i<=n;++i){
int a;
scanf("%d", &a);
add(i, a);
}
//区间修改初始化(即在初始化时应用了差分的思想)
long long last = 0, now;
for (int i = 1; i <= n; i++) {
scanf("%lld", &now);
add(i, now - last);
last = now;
}
int lowbit(int k) {
return k & -k;
}
//单点修改
void add(int x, int k) {
while (x <= n) {
tree[x] += k;
x += lowbit(x);
}
}
//那么当对 x ~ y 的区间进行修改的时候需要在树状数组中的第 x 个位置 + k, 第 y + 1 个位置 -k
eg:将[x,y]区间的数+k
add(x, k);
add(y + 1, -k);
当然对于区间修改,我们要是想将其转化为单点修改 只需令x=y,即可
//前缀和查询(若要求区间和的话,分别求得两端点前缀和,相减即可)
int sum(int x) {
int ans = 0;
while (x != 0) {
ans += tree[x];
x -= lowbit(x);
}
return ans;
}
eg:求[x,y]区间和
sum(y)-sum(x-1);
//单点查询
eg:查询第x位置的数值
sum(x)