bit区间增加区间求和,只不过是二维的......比一维麻烦多了。
这种题还是得自己推啊,强记果断会晕掉。
公式大概是ΣΣdij*(x-i+1)*(y-j+1),其中dij表示在(i,j)点上累计的增量,展开后得到ΣΣdij*(x+1)*(y+1)-dij*i*(y+1)-dij*j*(x+1)+dij*i*j 然后x+1和y+1是在具体询问中才知道的,所以我们维护4个bit:dij , dij*i , dij*j , dij*i*j 。
询问的时候注意上面乘i的下面要乘x+1,上面乘j的下面要乘y+1。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cmath> 5 #include<cstring> 6 #define maxn 2048 7 using namespace std; 8 int n,m; 9 struct bit 10 { 11 int b[maxn][maxn]; 12 void add(int x,int y,int z) 13 { 14 for (int i=x;i<=n;i+=(i&-i)) 15 for (int j=y;j<=m;j+=(j&-j)) 16 b[i][j]+=z; 17 } 18 int ask(int x,int y) 19 { 20 int tmp=0; 21 for (int i=x;i>0;i-=(i&-i)) 22 for (int j=y;j>0;j-=(j&-j)) 23 tmp+=b[i][j]; 24 return tmp; 25 } 26 }s,t,l,r; 27 28 void ins(int x1,int y1,int x2,int y2,int z) 29 { 30 s.add(x1,y1,z); s.add(x2+1,y1,-z); s.add(x1,y2+1,-z); s.add(x2+1,y2+1,z); 31 l.add(x1,y1,z*x1); l.add(x2+1,y1,-z*(x2+1)); l.add(x1,y2+1,-z*x1); l.add(x2+1,y2+1,z*(x2+1)); 32 r.add(x1,y1,z*y1); r.add(x2+1,y1,-z*y1); r.add(x1,y2+1,-z*(y2+1)); r.add(x2+1,y2+1,z*(y2+1)); 33 t.add(x1,y1,z*x1*y1); t.add(x2+1,y1,-z*(x2+1)*y1); t.add(x1,y2+1,-z*x1*(y2+1)); t.add(x2+1,y2+1,z*(x2+1)*(y2+1)); 34 } 35 36 int query(int x1,int y1,int x2,int y2) 37 { 38 int a1=s.ask(x2,y2)*(x2+1)*(y2+1)-s.ask(x1-1,y2)*x1*(y2+1)-s.ask(x2,y1-1)*(x2+1)*y1+s.ask(x1-1,y1-1)*x1*y1; 39 int a2=l.ask(x2,y2)*(y2+1)-l.ask(x1-1,y2)*(y2+1)-l.ask(x2,y1-1)*y1+l.ask(x1-1,y1-1)*y1; 40 int a3=r.ask(x2,y2)*(x2+1)-r.ask(x1-1,y2)*x1-r.ask(x2,y1-1)*(x2+1)+r.ask(x1-1,y1-1)*x1; 41 int a4=t.ask(x2,y2)-t.ask(x1-1,y2)-t.ask(x2,y1-1)+t.ask(x1-1,y1-1); 42 return a1-a2-a3+a4; 43 } 44 45 int main() 46 { 47 //freopen("make.in","r",stdin); 48 char sign[10]; 49 scanf("%s%d%d",sign,&n,&m); 50 int x1,x2,y1,y2; 51 int z; 52 while (scanf("%s",sign)!=EOF) 53 { 54 if (sign[0]=='L') 55 { 56 scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&z); 57 ins(x1,y1,x2,y2,z); 58 } 59 else 60 { 61 scanf("%d%d%d%d",&x1,&y1,&x2,&y2); 62 int ans=query(x1,y1,x2,y2); 63 printf("%d\n",ans); 64 } 65 } 66 return 0; 67 }
我实在想喷这个题的数据范围,实在太卡了,就是开小了re,开大了mle的节奏,建议大家开2050左右的int。