版权声明:蒟蒻Blog随意转载 https://blog.csdn.net/a1799342217/article/details/82153289
二维树状数组
学了一发二维树状数组。
维护序列区间修改的树状数组用了差分数组,那么维护矩阵修改的二维树状数组也一样。设 ,那么矩阵 的和即为 。同样展开化简可得 ,那么我们维护四个数组即可。
代码:
#include<cctype>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 2050
#define F inline
using namespace std;
int s,n,m,a[4][N][N];
F char readc(){
static char buf[100000],*l=buf,*r=buf;
if (l==r) r=(l=buf)+fread(buf,1,100000,stdin);
return l==r?EOF:*l++;
}
F int _read(){
int x=0,f=1; char ch=readc(); if (ch==EOF) return -1;
while (!isdigit(ch)&&!isalpha(ch)){
if (ch=='-') f=-1; ch=readc();
if (ch==EOF) return -1;
}
if (isalpha(ch)) return ch;
while (isdigit(ch)) x=(x<<3)+(x<<1)+(ch^48),ch=readc();
return x*f;
}
F void writec(int x){
if (x<0) putchar('-'),x=-x;
if (x>9) writec(x/10); putchar(x%10+48);
}
F void _write(int x){ writec(x),puts(""); }
F void mdfy(int x,int y,int w){
for (int i=x;i<=n;i+=i&-i)
for (int j=y;j<=m;j+=j&-j){
a[0][i][j]+=w,a[3][i][j]+=w*x*y;
a[1][i][j]+=w*x,a[2][i][j]+=w*y;
}
}
F int srch(int x,int y){
s=0;
for (int i=x;i;i-=i&-i)
for (int j=y;j;j-=j&-j){
s+=a[0][i][j]*(x+1)*(y+1)+a[3][i][j];
s-=a[1][i][j]*(y+1)+a[2][i][j]*(x+1);
}
return s;
}
int main(){
_read(),n=_read(),m=_read();
for (int f,x1,x2,y1,y2,w;;){
if ((f=_read())==-1) break;
x1=_read(),y1=_read(),x2=_read(),y2=_read();
if (f=='L'){
mdfy(x1,y1,w=_read()),mdfy(x2+1,y2+1,w);
mdfy(x1,y2+1,-w),mdfy(x2+1,y1,-w);
}
else _write(srch(x2,y2)-srch(x1-1,y2)-srch(x2,y1-1)+srch(x1-1,y1-1));
}
return 0;
}