#include<iostream>
#include<cstdio>
using namespace std;
int a[100005], n, m;
inline int lowbit(int x) {
return x & (-x);
}
void add(int x, int s) {
while (x <= n) {
a[x] += s;
x += lowbit(x);
}
}
int sum(int x) {
int ans = 0;
while (x > 0) {
ans += a[x];
x -= lowbit(x);
}
return ans;
}
int main()
{
int a, b, c;
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", &a, &b, &c);
if (a == 1)
add(b, c);
else
printf("%d\n", sum(c) - sum(b - 1));
}
return 0;
}
用前n个数的和表示第n个数,修改x-y区间就相当于第x个数+a,第y+1个数-a。这样就跟普通的树状数组一样了。
#include<iostream>
#include<cstdio>
using namespace std;
long long a[500005], n, m;
inline int lowbit(int x) {
return x & (-x);
}
void add(int x, long long s) {
while (x <= n) {
a[x] += s;
x += lowbit(x);
}
}
long long sum(int x) {
long long ans = 0;
while (x > 0) {
ans += a[x];
x -= lowbit(x);
}
return ans;
}
int main()
{
scanf("%d%d", &n, &m);
int k, x, y;
long long s, last(0);
for (int i = 1; i <= n; ++i) {
scanf("%lld", &s);
add(i, s - last);
last = s;
}
for (int i = 1; i <= m; ++i) {
scanf("%d", &k);
if (k == 1) {
scanf("%d%d%lld", &x, &y, &s);
add(x, s);
add(y + 1, -s);
}
else {
scanf("%d", &x);
printf("%lld\n", sum(x));
}
}
return 0;
}