思路:
和一维区间修改区间查询一样,用二维树状数组做,式子就是:
∑ i = 1 n ∑ j = 1 m a [ i ] = ∑ i = 1 n ∑ j = 1 m ∑ k = 1 i ∑ h = 1 j d i , j \sum_{i=1}^{n}\sum_{j=1}^{m}a[i]=\sum_{i=1}^{n}\sum_{j=1}^{m}\sum_{k=1}^{i}\sum_{h=1}^{j}d_{i,j} i=1∑nj=1∑ma[i]=i=1∑nj=1∑mk=1∑ih=1∑jdi,j
分别用4个树状数组维护即可
c o d e code code
#include<iostream>
#include<cstdio>
using namespace std;
long long n, m;
long long c[2500][2500][4];
long long lowbit(long long x){return x & -x;}
void add(long long x, long long y, long long k)
{
for(long long i=x; i<=n; i+=lowbit(i))
for(long long j=y; j<=m; j+=lowbit(j))
{
c[i][j][0]+=k;
c[i][j][1]+=k*x;
c[i][j][2]+=k*y;
c[i][j][3]+=k*x*y;
}
}
long long sum(long long x, long long y)
{
long long ans=0;
for(long long i=x; i; i-=lowbit(i))
for(long long j=y; j; j-=lowbit(j))
ans+=(x+1)*(y+1)*c[i][j][0]-c[i][j][1]*(y+1)-c[i][j][2]*(x+1)+c[i][j][3];
return ans;
}
int main()
{
scanf("%lld%lld", &n, &m);
long long z;
while(scanf("%lld", &z)!=EOF)
{
long long x, y, x1, y1, k;
scanf("%lld%lld%lld%lld", &x, &y, &x1, &y1);
if(z==1)
{
scanf("%lld", &k);
add(x, y, k), add(x, y1+1, -k), add(x1+1, y, -k), add(x1+1, y1+1, k);
}
else
{
printf("%lld\n", sum(x1, y1)-sum(x-1, y1)-sum(x1, y-1)+sum(x-1, y-1));
}
}
}