descirption
反正就是要你支持二维树状数组矩形修改矩形查询。
sol
类似于一维树状数组的区间修改区间查询(可以去参考lcf学长的blog),我们稍稍推一下式子。
假设原二维数组是(a_{i,j}),我们设其差分数组为(d_{i,j}=a_{i,j}-a_{i-1,j}-a_{i,j-1}+a_{i-1,j-1}),那么有:
[a_{x,y}=sum_{i=1}^xsum_{j=1}^yd_{i,j}\sum_{i=1}^{x}sum_{j=1}^ya_{i,j}=sum_{i=1}^xsum_{j=1}^ysum_{k=1}^isum_{l=1}^jd_{k,l}\=sum_{i=1}^{x}sum_{j=1}^yd_{i,j} imes(x-i+1) imes(y-j+1)\=(xy+x+y+1)sum_{i=1}^{x}sum_{j=1}^yd_{i,j}-(y+1)sum_{i=1}^{x}sum_{j=1}^yi imes d_{i,j}-(x+1)sum_{i=1}^{x}sum_{j=1}^yj imes d_{i,j}+sum_{i=1}^{x}sum_{j=1}^yij imes d_{i,j}
]
所以使用四个二维树状数组维护一下就可以了。复杂度(O(nlog^2n))
code
#include<cstdio>
#include<algorithm>
using namespace std;
int gi(){
int x=0,w=1;char ch=getchar();
while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
if (ch=='-') w=0,ch=getchar();
while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return w?x:-x;
}
#define ll long long
const int N = 2050;
int n,m;ll c[N][N],ci[N][N],cj[N][N],cij[N][N];
void modify(int x,int y,int v){
for (int i=x;i<=n;i+=i&-i)
for (int j=y;j<=m;j+=j&-j){
c[i][j]+=v;
ci[i][j]+=v*x;
cj[i][j]+=v*y;
cij[i][j]+=v*x*y;
}
}
ll query(int x,int y){
ll res=0;
for (int i=x;i;i-=i&-i)
for (int j=y;j;j-=j&-j){
res+=(x*y+x+y+1)*c[i][j];
res-=(y+1)*ci[i][j];
res-=(x+1)*cj[i][j];
res+=cij[i][j];
}
return res;
}
int main(){
n=gi();m=gi();char op;
while (scanf(" %c",&op)!=EOF)
if (op=='L'){
int a=gi(),b=gi(),c=gi(),d=gi(),v=gi();
modify(a,b,v);modify(a,d+1,-v);
modify(c+1,b,-v);modify(c+1,d+1,v);
}else{
int a=gi(),b=gi(),c=gi(),d=gi();
printf("%lld
",query(c,d)-query(a-1,d)-query(c,b-1)+query(a-1,b-1));
}
return 0;
}