http://poj.org/problem?id=1195
题意就是 对单点更新,每次对一个子矩阵求和啦。。。。
仅要实现这个功能的话,二维树状数组比二维线段树代码短了不是一点半点......
一维树状数组的更新
void add(int x,int val) { for(;x<=n;x+=lowbit(x)) { num[x]+=val; } }
void add(int x,int y,int a) { int i,j; for (i=x;i<=s;i+=lowbit(i)) { for (j=y;j<=s;j+=lowbit(j)) num[i][j]+=a; } }
int query(int x) { int ans=0; for(;x>0;x-=lowbit(x)) { ans+=a[i]; } return ans; }二维的查询
int query(int x,int y) { int ans=0,i,j; for (i=x;i>0;i-=lowbit(i)) { for (j=y;j>0;j-=lowbit(j)) ans+=num[i][j]; } return ans; }
#include <cstdio> #include <cmath> #include <cstring> #include <string> #include <algorithm> #include <queue> #include <set> #include <map> #include <vector> #include <iostream> using namespace std; #define ll int const double pi=acos(-1.0); double eps=1e-5; int max(int a,int b) {return a>b?a:b;} int min(int a,int b) {return a<b?a:b;} #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 int n,m; const int maxn=1000+50; int s; struct tree { int num[maxn][maxn]; inline int lowbit(int x) {return x&-x;} void add(int x,int y,int a) { int i,j; for (i=x;i<=s;i+=lowbit(i)) { for (j=y;j<=s;j+=lowbit(j)) num[i][j]+=a; } } int query(int x,int y) { int ans=0,i,j; for (i=x;i>0;i-=lowbit(i)) { for (j=y;j>0;j-=lowbit(j)) ans+=num[i][j]; } return ans; } }; tree tp; int main() { int i; int op; int a,x,y; int l,b,r,t; while(scanf("%d",&op)!=EOF) { if (op==3) break; if (op==0) { scanf("%d",&s); memset(tp.num,0,sizeof(tp.num)); } else if (op==1) { scanf("%d%d%d",&x,&y,&a); x++,y++; tp.add(x,y,a); } else { scanf("%d%d%d%d",&l,&b,&r,&t); l++,b++,r++,t++; int ret=tp.query(r,t); ret-=tp.query(l-1,t); ret-=tp.query(r,b-1); ret+=tp.query(l-1,b-1); printf("%d\n",ret); } } return 0; }