好困啊,想睡觉了。
题意:
一个二维矩阵,每个位置有一个整数,在线操作,修改点x,y的值,或者询问x,y到l,t之间的矩阵数值和。
裸的二维树状数组,二维的扩展很简单,就是在外层再套一个循环,至于为什么这样是合理的,先固定第一维来看,第二维总是合法的,因为它就是普通的树状数组操作,然后再把第二维看成一个黑盒,第一维也是一个普通的树状数组,所以也是合法的,所以二维树状数组只要朴素扩展就行了。
代码如下
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
using namespace std;
#define mxn 1100
int n;
int lowbit[mxn];
long long c[mxn][mxn];
void init(){
for(int i=1;i<=n;++i) lowbit[i]=i&(-i);
memset(c,0,sizeof(c));
}
void update(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;
}
long long sum(int x,int y){
long long ret=0;
for(int i=x;i;i-=lowbit[i])
for(int j=y;j;j-=lowbit[j])
ret+=c[i][j];
return ret;
}
long long find(int l,int b,int r,int t){
return sum(r,t)+sum(l,b)-sum(r,b)-sum(l,t);
}
int main(){
int kind;
int x,y,a;
int l,b,r,t;
scanf("%d%d",&kind,&n);
init();
while(scanf("%d",&kind)!=EOF&&kind!=3){
if(kind==1){
scanf("%d%d%d",&x,&y,&a);
update(x+1,y+1,a);
}
else{
scanf("%d%d%d%d",&l,&b,&r,&t);
printf("%I64d\n",find(l,b,r+1,t+1));
}
}
return 0;
}