Sol
对每个点
(i,j)
的操作都是覆盖了
(i,j)
~
(n,m)
的所有点的
Ai,j
表示
(i,j)
~
(n,m)
加的值
如果要求
(1,1)
~
(x,y)
数学表达式如上图所示
因此需要维护
Ai,j
,
Ai,j∗i
,
Ai,j∗j
,
Ai,j∗i∗j
四个前缀和
使用二维树状数组即可
参考博客
其实可以用容斥原理理解
Code
// by spli
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cstdio>
using namespace std;
const int N=2055;
int n,m;
int lowbit(int x){return x&(-x);}
struct BIT{
int c[N][N];
void add(int x,int y,int v){
for(int i=x;i<=n;i+=lowbit(i))
for(int j=y;j<=m;j+=lowbit(j))
c[i][j]+=v;
}
int query(int x,int y){
int ret=0;
for(int i=x;i;i-=lowbit(i))
for(int j=y;j;j-=lowbit(j))
ret+=c[i][j];
return ret;
}
}a,ai,aj,aij;
void update(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,z*x*y);
}
int ask(int x,int y){
int ret;
ret=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);
return ret;
}
int main(){
scanf("X %d%d",&n,&m);
//cout<<n<<" "<<m<<endl;
char op[5];
int a1,b1,a2,b2,z;
while(scanf("%s",op)!=EOF){
if(op[0]=='L'){
scanf("%d%d%d%d%d",&a1,&b1,&a2,&b2,&z);
update(a1,b1,z);
update(a1,b2+1,-z);
update(a2+1,b1,-z);
update(a2+1,b2+1,z);
}
else{
scanf("%d%d%d%d",&a1,&b1,&a2,&b2);
int ans;
ans=ask(a2,b2)-ask(a2,b1-1)-ask(a1-1,b2)+ask(a1-1,b1-1);
printf("%d\n",ans);
}
}
return 0;
}