BZOJ原题地址
洛谷原题地址
题面
写一个支持区间修改区间查询的二维数据结构。
请尝试自行推导公式。先放代码.
代码
#include
#define maxn 6000
using namespace std;
int n,m;
struct Bit{
int c[maxn][maxn];
int lb(int x){
return (x&-x);
}
void add(int x,int y,int z){
for (int i=x;i<=n;i+=lb(i))
for (int j=y;j<=m;j+=lb(j))
c[i][j]+=z;
}
int qry(int x,int y){
int r=0;
for (int i=x;i;i-=lb(i))
for (int j=y;j;j-=lb(j))
r+=c[i][j];
return r;
}
}A,B,C,D;
void Add(int x,int y,int z){
A.add(x,y,z),B.add(x,y,z*x),C.add(x,y,z*y),D.add(x,y,z*x*y);
}
int Qry(int x,int y){
return A.qry(x,y)*(x+1)*(y+1)-B.qry(x,y)*(y+1)-C.qry(x,y)*(x+1)+D.qry(x,y);
}
int main(){
ios::sync_with_stdio(false);
string X;cin>>X>>n>>m;
int a,b,x,y,T;
while(cin>>X){
cin>>a>>b>>x>>y;
if (X=="L"){
cin>>T;x++,y++;
Add(a,b,T),Add(x,y,T),Add(x,b,-T),Add(a,y,-T);
}
else{
a--,b--;
cout<
思路
用二维树状数组。
设原来的数组是 $a[i][j]$
有差分数组
公式挂掉了
区间加的时候,把一个区间拆成四个前缀区间,然后按定义维护$A,B,C,D$ 四个数组
求和直接用公式计算。