题意很明确,似乎可以写二维线段树,然而我并不会QAQ。
本来只会一点一维的树状数组区间修改区间查询,今天又见识到了二维的,好神奇Orz。
转自Only the Strong Survive的题解:
对于矩阵A,A[i][j]表示[i,j]-[n,m]的增量。那么子矩阵[1,1]-[x,y]的总和为:
无限ym
#include<bits/stdc++.h>
#define N 2050
using namespace std;
int n,m;
char ch[5];
inline int read()
{
int a=0,f=1; char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();}
while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();}
return a*f;
}
struct BIT
{
int tree[N][N];
inline int lowbit(int x)
{
return x&(-x);
}
inline void add(int x,int y,int val)
{
for (int i=x;i<=n;i+=lowbit(i))
for (int j=y;j<=m;j+=lowbit(j))
tree[i][j]+=val;
}
inline int query(int x,int y)
{
int tmp=0;
for (int i=x;i;i-=lowbit(i))
for (int j=y;j;j-=lowbit(j))
tmp+=tree[i][j];
return tmp;
}
} b1,b2,b3,b4;
inline void update(int x,int y,int val)
{
b1.add(x,y,val); b2.add(x,y,y*val); b3.add(x,y,x*val); b4.add(x,y,x*y*val);
}
inline int query(int x,int y)
{
return (x+1)*(y+1)*b1.query(x,y)-(x+1)*b2.query(x,y)-(y+1)*b3.query(x,y)+b4.query(x,y);
}
int main()
{
scanf("%s",ch);
n=read(); m=read();
int x1,x2,y1,y2,val;
while (scanf("%s",ch)!=EOF)
{
x1=read(); y1=read(); x2=read(); y2=read();
if (ch[0]=='L')
{
val=read();
update(x2+1,y2+1,val); update(x1,y1,val);
update(x2+1,y1,-val); update(x1,y2+1,-val);
}
else printf("%d\n",query(x2,y2)+query(x1-1,y1-1)-query(x1-1,y2)-query(x2,y1-1));
}
return 0;
}