P4514 上帝造题的七分钟(二维树状数组)
二维树状数组
差分维护区间加法,区间求和
#include<cstdio> int read(){ char c=getchar(); int x=0,f=1; while(c<'0'||c>'9') f=f&&(c!='-'),c=getchar(); while('0'<=c&&c<='9') x=x*10+c-48,c=getchar(); return f?x:-x; } int n,m; char q[3]; struct Tree_array{ int s[2051][2051]; void add(int x,int y,int v){ for(int i=x;i<=n;i+=i&-i) //直接用x,y来lowbit会挂掉,我也不知道为什么 for(int j=y;j<=m;j+=j&-j) s[i][j]+=v; } int sum(int x,int y){ int re=0; for(int i=x;i;i-=i&-i) for(int j=y;j;j-=j&-j) re+=s[i][j]; return re; } }a,ai,aj,aij; inline void Add(int i,int j,int v){ a.add(i,j,v),ai.add(i,j,v*i),aj.add(i,j,v*j),aij.add(i,j,v*i*j); } inline int Sum(int x,int y){ return a.sum(x,y)*(x*y+x+y+1)-ai.sum(x,y)*(y+1)-aj.sum(x,y)*(x+1)+aij.sum(x,y); } int main(){ scanf("%s",q); n=read(); m=read(); int a,b,c,d,v; while(~scanf("%s",q)){ a=read(); b=read(); c=read(); d=read(); if(q[0]=='L') v=read(),Add(a,b,v),Add(a,d+1,-v),Add(c+1,b,-v),Add(c+1,d+1,v); else printf("%d\n",Sum(c,d)-Sum(a-1,d)-Sum(c,b-1)+Sum(a-1,b-1)); }return 0; }