//由图可知,若求前7项的和,则该值为tree[7] + tree[6] + tree[4]
//故,通过循环可以求出结果
int sum(int x)
int ans = 0;
while(x != 0)
ans += tree[x];
x -= lowbit(x);
return ans;
完整代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 5e5 + 10;
int n, m, a, flag, p, q, tree[N];
int lowbit(int k)
return k & -k;
void add(int x, int k)
while(x <= n)
tree[x] += k;
x += lowbit(x);
int sum(int x)
int ans = 0;
while(x != 0)
ans += tree[x];
x -= lowbit(x);
return ans;
int main()
scanf("%d %d", &n, &m);
for(int i = 1; i <= n; ++i)
scanf("%d", &a);
add(i, a);
for(int i = 1; i <= m; ++i)
scanf("%d %d %d", &flag, &p, &q);
if(flag == 1)
add(p, q);
else
printf("%d\\n", sum(q) - sum(p - 1));
return 0;
区间修改,单点查询:
计算差分数组:
//与单点修改、区间查询类似
void add(int x, int k)
while(x <= n)
tree[x] += k;
x += lowbit(x);
计算每个点的值:
//与单点修改、区间查询类似
//此时计算的结果为每个点的值
int query(int x)
int ans = 0;
while(x != 0)
ans += tree[x];
x -= lowbit(x);
return ans;
完整代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 5e5 + 10;
int n, m, now, last, flag, p, q, num, tree[N];
int lowbit(int k)
return k & -k;
void add(int x, int k)
while(x <= n)
tree[x] += k;
x += lowbit(x);
int query(int x)
int ans = 0;
while(x != 0)
ans += tree[x];
x -= lowbit(x);
return ans;
int main()
scanf("%d %d", &n, &m);
//计算差分数组,将相差的值放入数组中
//eg.原本的数组应为a[] = 1, 6, 8, 5, 10
//则差分数组应为b[] = 1, 5, 2, -3, 5
for(int i = 1; i <= n; ++i)
scanf("%d", &now);
add(i, now - last);
last = now;
for(int i = 1; i <= m; ++i)
scanf("%d", &flag);
//若要修改区间[p, q]的值
//例如上述举的例子,若要将区间[2, 4]均加上3
//则原数组变为a[] = 1, 9, 11, 8, 10
//差分数组变为b[] = 1, 8, 2, -3, 2
//即对差分数组来说只需修改下标为p的值,和下标为q + 1的值
if(flag == 1)
scanf("%d %d %d", &p, &q, &num);
add(p, num);
add(q + 1, -num);
//若查询某个点的值
//前p个差分数组的值相加即为该点的值
//与单点修改、区间查询中的求前缀和类似
else
scanf("%d", &p);
printf("%d\\n", query(p));
return 0;
树状数组模板
树状数组是一个查询和修改复杂度都为 \(log\left(n\right)\) 的数据结构
所有树状数组能够完成的线段树都能够完成,而线段树能够完成的树状数组
- 那么既然线段树能够完成所有树状数组能够完成的,树状数组有什么用呢?
- 因为树状数组简洁,内存小,常数小
可以先百度一下树状数组了解树状数组
单点修改,区间查询
#include <cstdio>usingnamespace std;
void Update(int i,int x){
while (i<=MAX_TREE_SIZE) tr[i]+=x,i+=lowbit(i);
}
int Query(int i){
int sum=0;
while (i!=0) sum=sum+tr[i],i-=lowbit(i);
return sum;
}