首先要明确树状数组的本质就是带修改的前缀和,它每次用 lowbit 来很巧妙的寻找所属前缀的位置 在这些位置+k
然后还是用 lowbit 来查询这段和应该属于的树状数组的位置。
最简单的就是单点更新和区间查询,或者区间更新
int c[maxn];//树状数组 int n;//树状数组的大小 int lowbit(int x) { return x & (-x); } void update(int i,int k) { while(i>0) { c[i] += k; i -= lowbit(i); } } int getsum(int i)//前缀和思想 { int ans = 0; while (i <= n) { ans += c[i]; i += lowbit(i); } return ans; }
然后就是区间更新和单点查询
这个就要用到差分的思想了 差分学习
学习完差分之后,应该就感觉很简单了,就是树状数组存的是差分数组,
所以现在的区间更新就变成两点更新了,就更新了两个点。
然后就是区间更新和区间查询
这个区间查询有点复杂,直接看上面的公式吧。
维护了两个值,一个是sum1[] 一个是(i-1)*sum[i]
int sum1[maxn], sum2[maxn]; int n;//树状数组的大小 int lowbit(int x) { return x & (-x); } void update(int i,int k) { int x = i; while(i>0) { sum1[i] += k; sum2[i] += (x - 1)*k; i -= lowbit(i); } } int getsum(int i)//前缀和思想 { int x = i; int ans = 0; while (i <= n) { ans += x * sum1[i] - sum2[i]; i += lowbit(i); } return ans; }
原文地址:https://www.cnblogs.com/EchoZQN/p/11329798.html
时间: 2024-10-11 09:19:23