1、单点修改,区间查询
Pascal:
var
n,m,tt,x,y :longint;
c :array[0..500010] of longint;
i :longint;
function lowbit(x:longint):longint;
begin
exit(x and (-x));
end;
procedure add(x,v:longint);
begin
while (x<=n) do
begin
inc(c[x],v);
inc(x,lowbit(x));
end;
end;
function sum(x:longint):longint;
var
ans:longint;
begin
ans:=0;
while (x>0) do
begin
inc(ans,c[x]);
dec(x,lowbit(x));
end;
exit(ans);
end;
begin
read(n,m);
for i:=1 to n do
begin
read(x);
add(i,x);
end;
//
for i:=1 to m do
begin
read(tt,x,y);
if (tt=1) then add(x,y) else writeln(sum(y)-sum(x-1));
end;
end.
C(洛谷 P3374):
#include<stdio.h>
int n;
int c[500010];
int lowbit(int x) {
return(x & -x);
}
void add(int x, int v) {
while (x <= n) {
c[x] += v;
x += lowbit(x);
}
}
int get_sum(int x){
int ans = 0;
while (x > 0) {
ans += c[x];
x -= lowbit(x);
}
return(ans);
}
int main(){
int m;
int i;
int t, x, y;
scanf("%d %d", &n, &m);
for (i = 1; i <= n; i++) {
scanf("%d", &x);
add(i, x);
}
for (i = 1; i <= m; i++){
scanf("%d %d %d", &t, &x, &y);
if (t == 1) add(x, y); else printf("%d\n", get_sum(y) - get_sum(x - 1));
}
}
2、区间修改,单点查询
引入差分数组d,设原数组为a,令d[i]=a[i]-a[i-1].由此关系式得,也就是a[j]等于d[j]的前 j 项和,即前缀和。
于此,我们的树状数组维护的是 d 的前缀和。
1、单点查询:
有以上推理得,查询a[i]相当于查询d[i]的前缀和,用树状数组操作即可(树状数组维护的是d数组)
2、区间修改:
因为对a的区间[i,j]加x,就相当于a[i]比a[i-1]大x,a[j+1]比a[j]小x,就相当于对a[i]加x,对a[j+1]减x。
因为a[i]等于d[i]的前缀和,所以a[i]+x就相当于对d[i]的前缀和加x,可以用树状数组操作。
同理,a[j+1]-x等于b[j+1]的前缀和减x,用树状数组操作
pascal:
var
n,m,tt,x,y,z :longint;
c,a :array[0..500010] of longint;
i,j :longint;
function lowbit(x:longint):longint;
begin
exit(x and (-x));
end;
procedure add(x,v:longint);
begin
while (x<=n) do
begin
inc(c[x],v);
inc(x,lowbit(x));
end;
end;
function sum(x:longint):longint;
var
ans:longint;
begin
ans:=0;
while (x>0) do
begin
inc(ans,c[x]);
dec(x,lowbit(x));
end;
exit(ans);
end;
begin
read(n,m);
for i:=1 to n do read(a[i]);
for i:=1 to n do add(i,a[i]-a[i-1]); //注意
//
for i:=1 to m do
begin
read(tt);
if (tt=1) then
begin
read(x,y,z);
add(x,z);
add(y+1,-z);
end else
begin
read(x);
writeln(sum(x));
end;
end;
end.
C(洛谷P3368):
#include<stdio.h>
int a[500010], c[500010];
int n;
int lowbit(int x) {
return(x & -x);
}
void add(int x, int p) {
while (x <= n) {
c[x] += p;
x += lowbit(x);
}
}
int get_a(int x) {
int ans = 0;
while (x > 0) {
ans += c[x];
x -= lowbit(x);
}
return(ans);
}
int main () {
int m;
int i;
int x, t, l, r;
scanf("%d %d", &n, &m);
a[0] = 0;
for (i = 1; i <= n; i++) scanf("%d", &a[i]);
for (i = 1; i <= n; i++) add(i, a[i] - a[i-1]);
//
for (i = 1; i <= m; i++) {
scanf("%d", &t);
if (t == 2) {
scanf("%d" ,&x);
printf("%d\n", get_a(x));
} else {
scanf("%d %d %d", &l, &r, &x);
add(l, x);
add(r + 1, -x);
}
}
return 0;
}
——by Eirlys