树状数组二维区间加+区间查询模板bzoj3132

Posted nhc2014

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了树状数组二维区间加+区间查询模板bzoj3132相关的知识,希望对你有一定的参考价值。

新知识,其实和之前讲过的一维差不多,只要维护四个数组就行了,不过还是参考了别人的代码,还是要好好练练才行

#include<iostream>
#include<cstdio>
#include<cstring>
#define maxn 2050
using namespace std;
int a[maxn][maxn],b[maxn][maxn],c[maxn][maxn],d[maxn][maxn];
int n,m;
int lowbit(int x){return(x&-x);}
void update(int x,int y,int v,int g[][maxn])
{
  for (int i=x;i<=n;i+=lowbit(i)) for (int j=y;j<=m;j+=lowbit(j)) 
  g[i][j]+=v;
}
int query(int x,int y,int g[][maxn])
{
  int sum=0;
  for (int i=x;i>0;i-=lowbit(i))
  for (int j=y;j>0;j-=lowbit(j))
  sum+=g[i][j];
  return sum;
}
int calc(int x,int y)
{
  int sum=query(x,y,a)+query(x,y,b)*x+query(x,y,c)*y+query(x,y,d)*x*y;
  return sum;
}
void add(int x,int y,int v)
{
  if (!x||!y) return;
  update(x,y,x*y*v,a);
  update(x,y,y*-v,b); update(1,y,y*v,b);
  update(x,y,x*-v,c); update(x,1,x*v,c);
  update(x,y,v,d);update(1,1,v,d);
  update(x,1,-v,d);update(1,y,-v,d);
//这里是重点,在访问到当前的时候,会加上一个值,过了边界的时候再减去这个值 }
int main() { char ch; scanf("%c %d%d",&ch,&n,&m); int x,y,xx,yy,val; while (scanf("\n%c ",&ch)!=EOF) { if (ch==L) { scanf("%d%d%d%d%d",&x,&y,&xx,&yy,&val); add(x-1,y-1,val);add(xx,yy,val);add(xx,y-1,-val);add(x-1,yy,-val); } else { scanf("%d%d%d%d",&x,&y,&xx,&yy);x--;y--; int ans=calc(xx,yy)-calc(xx,y)-calc(x,yy)+calc(x,y); printf("%d\n",ans); } } return 0; }

 

以上是关于树状数组二维区间加+区间查询模板bzoj3132的主要内容,如果未能解决你的问题,请参考以下文章

bzoj5173[Jsoi2014]矩形并 扫描线+二维树状数组区间修改区间查询

树状数组区间加+区间查询模板洛谷P3372

bzoj3132 上帝造题的七分钟(差分+二维树状数组)

P3372 模板线段树 1(区间修改区间查询)(树状数组)

BZOJ 4785 [Zjoi2017]树状数组 | 二维线段树

BZOJ 3594 [Scoi2014]方伯伯的玉米田(二维树状数组)