【树状数组二维区间加+区间查询模板】bzoj3132

时间:2022-09-03 11:58:27

新知识,其实和之前讲过的一维差不多,只要维护四个数组就行了,不过还是参考了别人的代码,还是要好好练练才行

#include<iostream>
#include
<cstdio>
#include
<cstring>
#define maxn 2050
using namespace std;
int a[maxn][maxn],b[maxn][maxn],c[maxn][maxn],d[maxn][maxn];
int n,m;
int lowbit(int x){return(x&-x);}
void update(int x,int y,int v,int g[][maxn])
{
for (int i=x;i<=n;i+=lowbit(i)) for (int j=y;j<=m;j+=lowbit(j))
g[i][j]
+=v;
}
int query(int x,int y,int g[][maxn])
{
int sum=0;
for (int i=x;i>0;i-=lowbit(i))
for (int j=y;j>0;j-=lowbit(j))
sum
+=g[i][j];
return sum;
}
int calc(int x,int y)
{
int sum=query(x,y,a)+query(x,y,b)*x+query(x,y,c)*y+query(x,y,d)*x*y;
return sum;
}
void add(int x,int y,int v)
{
if (!x||!y) return;
update(x,y,x
*y*v,a);
update(x,y,y
*-v,b); update(1,y,y*v,b);
update(x,y,x
*-v,c); update(x,1,x*v,c);
update(x,y,v,d);update(
1,1,v,d);
update(x,
1,-v,d);update(1,y,-v,d);
//这里是重点,在访问到当前的时候,会加上一个值,过了边界的时候再减去这个值}
int main()
{
char ch;
scanf(
"%c %d%d",&ch,&n,&m);
int x,y,xx,yy,val;
while (scanf("\n%c ",&ch)!=EOF)
{
if (ch=='L')
{
scanf(
"%d%d%d%d%d",&x,&y,&xx,&yy,&val);
add(x
-1,y-1,val);add(xx,yy,val);add(xx,y-1,-val);add(x-1,yy,-val);
}
else
{
scanf(
"%d%d%d%d",&x,&y,&xx,&yy);x--;y--;
int ans=calc(xx,yy)-calc(xx,y)-calc(x,yy)+calc(x,y);
printf(
"%d\n",ans);
}
}
return 0;
}