题目
一开始初始为0的二维数组,需要维护区间加和区间查询
分析
首先要思考如何表示二维前缀和以差分实现
所以这四个东西用树状数组维护
代码
#include <cstdio>
#include <cctype>
#define rr register
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<13,stdin)),p1==p2?EOF:*p1++)
using namespace std;
int n,m; char buf[1<<13],*p1,*p2;
inline signed iut(){
rr int ans=0,f=1; rr char c=getchar();
while (!isdigit(c)) f=(c=='-')?-f:f,c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans*f;
}
inline void print(int ans){
if (ans<0) putchar('-'),ans=-ans;
if (ans>9) print(ans/10);
putchar(ans%10+48);
}
struct lowbit{
int c[2051][2051];
inline void add(int x,int y,int z){
rr int y1=y;
for (;x<=n;x+=-x&x)
for (y=y1;y<=m;y+=-y&y) c[x][y]+=z;
}
inline signed query(int x,int y){
rr int ans=0,y1=y;
for (;x;x-=-x&x)
for (y=y1;y;y-=-y&y) ans+=c[x][y];
return ans;
}
}a,a_x,a_y,a_xy;
inline void Add(int x,int y,int z){a.add(x,y,z),a_x.add(x,y,z*x),a_y.add(x,y,z*y),a_xy.add(x,y,z*x*y);}
inline signed Query(int x,int y){return a.query(x,y)*(x*y+x+y+1)-a_x.query(x,y)*(y+1)-a_y.query(x,y)*(x+1)+a_xy.query(x,y);}
signed main(){
n=iut(),m=iut(),getchar();
for (rr char c=getchar();c=='k'||c=='L';getchar(),c=getchar()){
rr int x1=iut(),y1=iut(),x2=iut(),y2=iut(),z;
if (c=='L') z=iut();
if (c=='L') Add(x1,y1,z),Add(x2+1,y1,-z),Add(x1,y2+1,-z),Add(x2+1,y2+1,z);
else print(Query(x2,y2)-Query(x1-1,y2)-Query(x2,y1-1)+Query(x1-1,y1-1)),putchar(10);
}
return 0;
}
转载:https://blog.csdn.net/sugar_free_mint/article/details/102132283
查看评论