地址:http://poj.org/problem?id=1195
题意:
0 s: s*s的初始为0的矩阵a[][]
1 X Y A:a[x][y]+A
2 L B R T:左上角a[L][B]到右下角a[R][T]的矩阵和。
解析:
二维数组数组板子,和一维基本类似:
void update(int x,int y,int z) { // cout<<"?"; for(int i=x;i<=n;i+=lowbit(i)) for(int j=y;j<=n;j+=lowbit(j)) c[i][j]+=z; } int getsum(int x,int y) { int sum = 0 ; for(int i=x;i>=1;i-=lowbit(i)) for(int j=y;j>=1;j-=lowbit(j)) sum+=c[i][j]; return sum; }
求和,画图即可理解,左上角被减去了两次。
坐标都要记得+1,因为树状数组i=0时无效
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int maxn=1200; int c[maxn][maxn]; int x,n; int lowbit(int x) { return x&(-x); } void update(int x,int y,int z) { // cout<<"?"; for(int i=x;i<=n;i+=lowbit(i)) for(int j=y;j<=n;j+=lowbit(j)) c[i][j]+=z; } int getsum(int x,int y) { int sum = 0 ; for(int i=x;i>=1;i-=lowbit(i)) for(int j=y;j>=1;j-=lowbit(j)) sum+=c[i][j]; return sum; } int getall(int x1,int y1,int x2,int y2) { return getsum(x2,y2)-getsum(x1-1,y2)-getsum(x2,y1-1)+getsum(x1-1,y1-1); } int main() { while(scanf("%d",&x)!=EOF) { if(x==0) { scanf("%d",&n); memset(c,0,sizeof(c)); } else if(x==1) { int i,j,y; scanf("%d%d%d",&i,&j,&y); update(i+1,j+1,y); } else if(x==2) { int x1,y1,x2,y2; scanf("%d%d%d%d",&x1,&y1,&x2,&y2); cout<<getall(x1+1,y1+1,x2+1,y2+1)<<endl; } } }