树状数组是一个查询和修改复杂度都为log(n)的数据结构,
单点修改、区间询问
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int MAX_N=32005;
const int maxn=15010;
int n,tre[MAX_N];
int lowbit(int x){//最低位的一
return x&-x;
}
void add(int i,int val){//修改,更新后缀和。
for(;i<=MAX_N;i+=lowbit(i)){//MAX_A很关键
tre[i]+=val;
}
}
int sum(int i){//1~x的和,t从1开始标号
int ans=0;
for(;i>0;i-=lowbit(i)){
ans+=tre[i];
}
return ans;
}
区间修改、单点询问
#include<bits/stdc++.h>
using namespace std;
const int maxn = 5e5+5;
int n,m;
int c[maxn];
int lowbit(int x){return x&-x;}
void add(int i,int val){
for(;i<=n;i+=lowbit(i))
c[i] += val;
}
int query(int i){
int res = 0;
for(;i>0;i-=lowbit(i)){
res += c[i];
}
return res;
}
int main() {
scanf("%d%d",&n,&m);
int x,y=0;
for(int i=1;i<=n;i++){
scanf("%d",&x);
add(i,x-y);
y = x;
}
int op,k;
for(int i=1;i<=m;i++){
scanf("%d",&op);
if(op==1){
scanf("%d%d%d",&x,&y,&k);
add(x,k);
add(y+1,-k);
}
else {
scanf("%d",&x);
printf("%d\n",query(x));
}
}
return 0;
}
区间修改、区间查询
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5+5;
int n,m;
ll c1[maxn],c2[maxn];
int lowbit(int x){return x&-x;}
void add(int x,int val){
for(int i=x;i<=n;i+=lowbit(i)){
c1[i] += val;
c2[i] += 1ll*x*val;
}
}
ll query(int x){
ll res = 0;
for(int i=x;i;i-=lowbit(i))
res += c1[i]*(x+1) - c2[i];
return res;
}
int main() {
scanf("%d%d",&n,&m);
int x,y=0;
for(int i=1;i<=n;i++){
scanf("%d",&x);
add(i,x-y);
y = x;
}
int op,k;
for(int i=1;i<=m;i++){
scanf("%d",&op);
if(op==1){
scanf("%d%d%d",&x,&y,&k);
add(x,k);
add(y+1,-k);
}
else {
scanf("%d%d",&x,&y);
printf("%lld\n",query(y)-query(x-1));
}
}
return 0;
}
refrence:
https://www.cnblogs.com/RabbitHu/p/BIT.html
树状数组题集https://www.xuebuyuan.com/3194885.html