思路
根据例题4的思路,我们要先知道怎么差分,设
d
i
,
j
d_{i,j}
di,j 表示
(
i
,
j
)
(i,j)
(i,j) 位置上的差分数组。
那么我们的差分思路是将
d
x
1
,
y
1
+
=
k
,
d
x
1
,
y
2
+
1
−
=
k
,
d
x
2
+
1
,
y
1
−
=
k
,
d
x
2
+
1
,
y
2
+
1
+
=
k
d_{x1,y1}+=k,d_{x1,y2+1}-=k,d_{x2+1,y1}-=k,d_{x2+1,y2+1}+=k
dx1,y1+=k,dx1,y2+1−=k,dx2+1,y1−=k,dx2+1,y2+1+=k
我们维护的前缀和即:
∑
i
=
1
n
∑
j
=
1
m
a
i
,
j
=
∑
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,j}=\sum_{i=1}^{n}\sum_{j=1}^{m}\sum_{k=1}^{i}\sum_{h=1}^{j}d_{i,j}
i=1∑nj=1∑mai,j=i=1∑nj=1∑mk=1∑ih=1∑jdi,j
其中
d
i
,
j
d_{i,j}
di,j 出现了
(
n
−
i
+
1
)
×
(
m
−
j
+
1
)
(n-i+1)\times(m-j+1)
(n−i+1)×(m−j+1) 次,那么
∑
i
=
1
n
∑
j
=
1
m
∑
k
=
1
i
∑
h
=
1
j
d
i
,
j
=
\sum_{i=1}^{n}\sum_{j=1}^{m}\sum_{k=1}^{i}\sum_{h=1}^{j}d_{i,j}=
i=1∑nj=1∑mk=1∑ih=1∑jdi,j=
∑
i
=
1
n
∑
j
=
1
m
(
(
n
+
1
)
×
(
m
+
1
)
×
d
i
,
j
−
(
m
+
1
)
×
d
i
,
j
×
i
−
(
n
+
1
)
×
d
i
,
j
×
j
+
d
i
,
j
×
i
×
j
)
\sum_{i=1}^{n}\sum_{j=1}^{m}((n+1)\times(m+1)\times d_{i,j}-(m+1)\times d_{i,j}\times i-(n+1)\times d_{i,j}\times j+d_{i,j}\times i\times j)
i=1∑nj=1∑m((n+1)×(m+1)×di,j−(m+1)×di,j×i−(n+1)×di,j×j+di,j×i×j)用树状数组分别维护
d
i
,
j
,
d
i
,
j
×
i
,
d
i
,
j
×
j
,
d
i
,
j
×
i
×
j
d_{i,j},d_{i,j}\times i,d_{i,j}\times j,d_{i,j}\times i\times j
di,j,di,j×i,di,j×j,di,j×i×j。
代码
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
long long c[2500][2500][4];
int n,m,w,a,b,cc,d,k;
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+=c[i][j][0]*(x+1)*(y+1)-c[i][j][1]*(y+1)-c[i][j][2]*(x+1)+c[i][j][3];
return ans;
}
int main()
{
scanf("%d%d",&n,&m);
while(scanf("%d",&w)!=EOF)
{
scanf("%d%d%d%d",&a,&b,&cc,&d);
if(w==1)
{
scanf("%d",&k);
add(a,b,k),add(a,d+1,-k);
add(cc+1,b,-k),add(cc+1,d+1,k);
}
else
printf("%lld\n",sum(cc,d)-sum(cc,b-1)-sum(a-1,d)+sum(a-1,b-1));
}
return 0;
}