树状数组Binary Indexed Tree(2):区间修改,单点查询
程序员文章站
2024-03-03 15:48:28
...
Description
给定数列a[1],a[2]…,a[n],需要依次执行q个操作。
操作分两类:
1 l r x : 给定l,r,x,对于所有 i
∈
\in
∈ [l,r],将a[i]加上x
2 i :求a[i]的值
(1
≤
\leq
≤ n,q
≤
\leq
≤ 106)
解题思路
算法标签:树状数组
利用差分的思想。设原数组number[i],d[i] = number[i] - number[i-1],所以number[i] =
∑
j
=
1
i
d
[
j
]
\sum_{j=1}^id[j]
∑j=1id[j],即可以通过求d[i]的前缀和查询。修改通过给d[l]加上x,给d[r+1]减上x
代码
// TSWorld
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1000009;
long long tree[N];
int number[N];
int n, q;
inline int lowbit(long long x) { return x & (-x); }
void Change(int index, int delta) {
while (index <= n) {
tree[index] += delta;
index += lowbit(index);
}
}
long long Query(long long index) {
long long sum = 0;
while (index > 0) {
sum += tree[index];
index -= lowbit(index);
}
return sum;
}
int main() {
int cmd = 0, l = 0, r = 0, x = 0;
cin >> n >> q;
for (int i = 1; i <= n; i++) {
scanf("%d", &number[i]);
Change(i, number[i] - number[i - 1]);
}
for (int i = 1; i <= q; i++) {
scanf("%d", &cmd);
if (cmd == 1) {
scanf("%d%d%d", &l, &r, &x);
Change(l, x);
Change(r + 1, -x);
} else {
scanf("%d", &l);
printf("%lld\n", Query(l));
}
}
return 0;
}