Solution
二维树状数组
求 (x1,y1)(x1,y1) 到 (x2,y2)(x2,y2) 的和 sum=sum[x2][y2]−sum[x1−1][y2]−sum[x2][y1−1]+sum[x1−1][y1−1]sum=sum[x2][y2]−sum[x1−1][y2]−sum[x2][y1−1]+sum[x1−1][y1−1]
sum[x][y]=∑i=1x∑j=1y∑k=1i∑t=1ja[k][t]=∑i=1x∑j=1xa[i][j]∗(x−i+1)∗(y−j+1)sum[x][y]=∑i=1x∑j=1y∑k=1i∑t=1ja[k][t]=∑i=1x∑j=1xa[i][j]∗(x−i+1)∗(y−j+1)
sum[x][y]=∑i=1x∑j=1y∑k=1i∑t=1ja[k][t]=∑i=1x∑j=1xa[i][j]∗(x−i+1)∗(y−j+1)=∑i=1x∑j=1xa[i][j]∗(xy−xj−yi++ij+x+y−i−j+1)=∑i=1x∑j=1xa[i][j]∗(xy+x+y+1)−a[i][j]∗i∗(y+1)−a[i][j]∗j∗(x+1)+a[i][j]∗i∗jsum[x][y]=∑i=1x∑j=1y∑k=1i∑t=1ja[k][t]=∑i=1x∑j=1xa[i][j]∗(x−i+1)∗(y−j+1)=∑i=1x∑j=1xa[i][j]∗(xy−xj−yi++ij+x+y−i−j+1)=∑i=1x∑j=1xa[i][j]∗(xy+x+y+1)−a[i][j]∗i∗(y+1)−a[i][j]∗j∗(x+1)+a[i][j]∗i∗j
因此我们开四个二维树状数组就可以解决了
Code
#include <cstdio>
#define N 2050
int n,m,a,b,c,d,k;
char str[10];
struct BIT{
int tree[N][N];
void add(int x,int y,int z){
for(int i=x;i<=n;i+=i&(-i))
for(int j=y;j<=m;j+=j&(-j))
tree[i][j]+=z;
}
int query(int x,int y){
int ans=0;
for(int i=x;i;i-=i&-i)
for(int j=y;j;j-=j&-j)
ans+=tree[i][j];
return ans;
}
}A,Ai,Aj,Aij;
inline void add(int x,int y,int z){
A.add(x,y,z);
Ai.add(x,y,z*x);
Aj.add(x,y,z*y);
Aij.add(x,y,x*y*z);
}
inline int query(int x,int y){
return A.query(x,y)*(x*y+x+y+1)-Ai.query(x,y)*(y+1)-Aj.query(x,y)*(x+1)+Aij.query(x,y);
}
int main(){
scanf("%s%d%d",str,&n,&m);
while(scanf("%s%d%d%d%d",str,&a,&b,&c,&d)>0){
if(str[0]=='L'){
scanf("%d",&k);
add(a,b,k);
add(a,d+1,-k);
add(c+1,b,-k);
add(c+1,d+1,k);
}else printf("%d\n",query(c,d)-query(a-1,d)-query(c,b-1)+query(a-1,b-1));
}
return 0;
}