【数据结构】树状数组【模板】
证明什么的待补
一维
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+7;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
ll a[N],c[N],n;
inline int lowbit(int x){
return x&-x;
}
inline void add(int i,int x){
while(i<=n){
c[i]+=x;
i+=lowbit(i);
}
return ;
}
inline ll sum(int i){
ll res=0;
while(i){
res+=c[i];
i-=lowbit(i);
}
return res;
}
int main(){
int q;
n=read();q=read();
for(int i=1;i<=n;i++){
int x;
x=read();
add(i,x);
}
while(q--){
int l,r,w;
w=read();l=read();r=read();
if(w==1) add(l,r);
else {
ll res=sum(r)-sum(l-1);
printf("%lld\n",res);
}
}
return 0;
}
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+7;
ll a[N],c[N];//原数组和树状数组
ll n;
inline ll read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
inline ll lowbit(ll x){
return x&-x;
}
void add(ll i,ll k){
while(i<=n){
c[i]+=k;
i+=lowbit(i);
}
}
ll sum(ll i){//求a[1]到a[n]的和
ll res=0;
while(i>0){
res+=c[i];
i-=lowbit(i);
}
return res;
}
int main(){
ll q,x;
n=read();q=read();
for(ll i=1;i<=n;i++){
a[i]=read();
add(i,a[i]-a[i-1]);
}
while(q--){
ll a,b,c,d;
a=read();
if(a==1){
b=read();c=read();d=read();
add(b,d);
add(c+1,-d);
}
else{
b=read();
printf("%lld\n",sum(b));
}
}
return 0;
}
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+7;
ll a[N],sum1[N],sum2[N];
ll n,m;
inline ll read()
{
ll x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
inline ll lowbit(ll x){
return x&-x;
}
inline void update(ll i,ll k){
ll x=i;
while(i<=n){
sum1[i]+=k;
sum2[i]+=k*(x-1);
i+=lowbit(i);
}
}
inline ll sum(int i){
ll res=0,x=i;
while(i>0){
res+=x*sum1[i]-sum2[i];
i-=lowbit(i);
}
return res;
}
int main(){
n=read();m=read();
for(ll i=1;i<=n;i++){
cin>>a[i];
update(i,a[i]-a[i-1]);
}
while(m--){
ll k,l,r,x;
k=read();
if(k==1){
l=read();r=read();x=read();
update(l,x);
update(r+1,-x);
}
else{
l=read();r=read();
ll res=sum(r)-sum(l-1);
printf("%lld\n",res);
}
}
return 0;
}
二维
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=5500;
ll a[N][N],n,m;
inline ll read()
{
ll x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
ll lowbit(ll x){
return x&-x;
}
void update(ll x,ll y,ll v){
for(int i=x;i<=n;i+=lowbit(i))
for(int j=y;j<=m;j+=lowbit(j))
a[i][j]+=v;
}
ll sum(ll x,ll y){
ll res=0;
for(int i=x;i>0;i-=lowbit(i))
for(int j=y;j>0;j-=lowbit(j))
res+=a[i][j];
return res;
}
ll query(ll x1,ll y1,ll x2,ll y2){
return sum(x1,y1)-sum(x1,y2-1)-sum(x2-1,y1)+sum(x2-1,y2-1);
}
int main(){
while(~scanf("%d%d",&n,&m)){
memset(a,0,sizeof a);
int op;
while(~scanf("%d",&op)){
if(op==1){
ll x,y,k;
x=read();y=read();k=read();
//cin>>x>>y>>k;
update(x,y,k);
}
else{
ll a,b,c,d;
c=read();d=read();a=read();b=read();
//cin>>a>>b>>c>>d;
printf("%lld\n",query(a,b,c,d));
}
}
}
return 0;
}
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2100;
ll t1[N][N],t2[N][N],t3[N][N],t4[N][N];
ll n,m;
ll lowbit(ll x){
return x&(-x);
}
void add(ll x,ll y,ll v){
for(ll i=x;i<=n;i+=lowbit(i))
for(ll j=y;j<=m;j+=lowbit(j)){
t1[i][j]+=v;
t2[i][j]+=v*x;
t3[i][j]+=v*y;
t4[i][j]+=v*x*y;
}
}
void update(ll x1,ll y1,ll x2,ll y2,ll v){
add(x1,y1,v);
add(x1,y2+1,-v);
add(x2+1,y1,-v);
add(x2+1,y2+1,v);
}
ll sum(ll x,ll y){
ll res=0;
for(ll i=x;i>0;i-=lowbit(i))
for(ll j=y;j>0;j-=lowbit(j))
res+=(x+1)*(y+1)*t1[i][j]-(y+1)*t2[i][j]-(x+1)*t3[i][j]+t4[i][j];
return res;
}
ll query(ll x1,ll y1,ll x2,ll y2){
return sum(x2,y2)+sum(x1-1,y1-1)-sum(x2,y1-1)-sum(x1-1,y2);
}
int main(){
scanf("%lld%lld", &n, &m);
int op;
while(~scanf("%d",&op)){
if(op==1){
ll a,b,c,d,x;
scanf("%lld%lld%lld%lld%lld", &a, &b, &c, &d, &x);
// a=read();b==read();c=read();d=read();x=read();
update(a,b,c,d,x);
}
else{
ll a,b,c,d;
scanf("%lld%lld%lld%lld", &a, &b, &c, &d);
//a=read();b==read();c=read();d=read();
printf("%lld\n",query(a,b,c,d));
}
}
return 0;
}
参考博客:树状数组详解 - Xenny - 博客园 (吹爆这篇!)
彻底弄懂二维树状数组_ó-CSDN博客
二维树状数组总结及模板_kangdi的博客-CSDN博客