题目大意:
对一个矩阵上的某个值进行修改,然后求出子矩阵的和。
思路分析:
这题discuss 上说二维线段树过不了。
所以二维树状数组搞。
理解树状数组的意义就是 1 - n 上所有的和。
然后两重循环。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#define maxn 1040
#define lowbit(x) (x&(-x))
using namespace std;
int C[maxn][maxn];
int n;
void add(int x,int y,int a)
{
for(int i=x;i<=n;i+=lowbit(i))
{
for(int j=y;j<=n;j+=lowbit(j))
{
C[i][j]+=a;
}
}
//printf("out %d %d\n",x,y);
}
int Sum(int L,int B,int R,int T)
{
int res=0;
for(; R>0 ; R -=lowbit(R))
{
int p=0,q=0;
for(int i=T ; i>0 ; i-=lowbit(i))p+=C[R][i];
for(int i=B-1; i>0 ; i-=lowbit(i))q+=C[R][i];
res+=p-q;
}
int ret=0;
for(L=L-1; L>0 ;L-=lowbit(L))
{
int p=0,q=0;
for(int i=T; i>0 ;i-=lowbit(i))p+=C[L][i];
for(int i=B-1; i>0 ;i-=lowbit(i))q+=C[L][i];
ret+=p-q;
}
//printf("%d %d\n",res,ret);
return res-ret;
}
void debug()
{
for(int i=1;i<=4;i++)
{
for(int j=1;j<=4;j++)
{
printf("%d ",C[i][j]);
}
puts("");
}
}
int main()
{
int op;
while(scanf("%d",&op)!=EOF)
{
if(op==0)
{
scanf("%d",&n);
memset(C,0,sizeof C);
}
else if(op==1)
{
int x,y;
int a;
scanf("%d%d%d",&x,&y,&a);
x++,y++;
add(x,y,a);
}
else if(op==2)
{
int L,B,R,T;
scanf("%d%d%d%d",&L,&B,&R,&T);
L++,B++,R++,T++;
printf("%d\n",Sum(L,B,R,T));
}
else break;
//debug();
}
return 0;
}