二维线段树

 

https://www.luogu.org/problemnew/show/U22582

 

  1 #include <cstdio>
  2 #include <cstdlib>
  3 #include <cmath>
  4 #include <algorithm>
  5 #include <iostream>
  6 using namespace std;
  7 #define ll long long
  8 
  9 const int maxn=2e3+10;
 10 const int maxg=2000*2000*16;///8=2*2*2(two dimensions)
 11 
 12 ll sum[maxg],tag[maxg];
 13 ll a[maxn][maxn];
 14 
 15 void build(int ind,int xl,int xr,int yl,int yr)
 16 {
 17     ///千万注意,不是按照二维读入的顺序的
 18     if (xl==xr && yl==yr)
 19         sum[ind]=a[xl][yl];
 20     else
 21     {
 22         int xm=(xl+xr)>>1;
 23         int ym=(yl+yr)>>1;
 24         build(ind*4,xl,xm,yl,ym);
 25         if (ym<yr)
 26             build(ind*4+1,xl,xm,ym+1,yr);
 27         if (xm<xr)
 28             build(ind*4+2,xm+1,xr,yl,ym);
 29         if (xm<xr && ym<yr)
 30             build(ind*4+3,xm+1,xr,ym+1,yr);
 31         sum[ind]=sum[ind*4]+sum[ind*4+1]+sum[ind*4+2]+sum[ind*4+3];
 32     }
 33 }
 34 
 35 void push_down(int ind,int xl,int xr,int yl,int yr)
 36 {
 37     int xm=(xl+xr)>>1;
 38     int ym=(yl+yr)>>1;
 39 
 40     sum[ind*4]+=tag[ind]*(xm-xl+1)*(ym-yl+1);
 41     sum[ind*4+1]+=tag[ind]*(xm-xl+1)*(yr-ym);
 42     sum[ind*4+2]+=tag[ind]*(xr-xm)*(ym-yl+1);
 43     sum[ind*4+3]+=tag[ind]*(xr-xm)*(yr-ym);
 44 
 45     tag[ind*4]+=tag[ind];
 46     tag[ind*4+1]+=tag[ind];
 47     tag[ind*4+2]+=tag[ind];
 48     tag[ind*4+3]+=tag[ind];
 49 
 50     tag[ind]=0;
 51 }
 52 
 53 void update(int ind,int xl,int xr,int yl,int yr,int ul,int ur,int vl,int vr,ll v)
 54 {
 55     if (ul<=xl && xr<=ur && vl<=yl && yr<=vr)
 56     {
 57         sum[ind]+=v*(xr-xl+1)*(yr-yl+1);
 58         tag[ind]+=v;
 59         return;
 60     }
 61     if (tag[ind]!=0)
 62         push_down(ind,xl,xr,yl,yr);
 63     int xm=(xl+xr)>>1;
 64     int ym=(yl+yr)>>1;
 65     if (ul<=xm && vl<=ym)
 66         update(ind*4,xl,xm,yl,ym,ul,ur,vl,vr,v);
 67     if (ul<=xm && ym<vr && ym<yr)
 68         update(ind*4+1,xl,xm,ym+1,yr,ul,ur,vl,vr,v);
 69     if (xm<ur && vl<=ym && xm<xr)
 70         update(ind*4+2,xm+1,xr,yl,ym,ul,ur,vl,vr,v);
 71     if (xm<ur && ym<vr && xm<xr && ym<yr)
 72         update(ind*4+3,xm+1,xr,ym+1,yr,ul,ur,vl,vr,v);
 73     sum[ind]=sum[ind*4]+sum[ind*4+1]+sum[ind*4+2]+sum[ind*4+3];
 74 }
 75 
 76 ll query(int ind,int xl,int xr,int yl,int yr,int ul,int ur,int vl,int vr)
 77 {
 78     if (tag[ind]!=0)
 79         push_down(ind,xl,xr,yl,yr);
 80     if (ul<=xl && xr<=ur && vl<=yl && yr<=vr)
 81         return sum[ind];
 82     ll tot=0;
 83     int xm=(xl+xr)>>1;
 84     int ym=(yl+yr)>>1;
 85     if (ul<=xm && vl<=ym)
 86         tot+=query(ind*4,xl,xm,yl,ym,ul,ur,vl,vr);
 87     if (ul<=xm && ym<vr && ym<yr)
 88         tot+=query(ind*4+1,xl,xm,ym+1,yr,ul,ur,vl,vr);
 89     if (xm<ur && vl<=ym && xm<xr)
 90         tot+=query(ind*4+2,xm+1,xr,yl,ym,ul,ur,vl,vr);
 91     if (xm<ur && ym<vr && xm<xr && ym<yr)
 92         tot+=query(ind*4+3,xm+1,xr,ym+1,yr,ul,ur,vl,vr);
 93     sum[ind]=sum[ind*4]+sum[ind*4+1]+sum[ind*4+2]+sum[ind*4+3];
 94     return tot;
 95 }
 96 
 97 int main()
 98 {
 99     int n,m,q,x1,x2,y1,y2,mode,v,i,j;
100     scanf("%d%d%d",&n,&m,&q);
101     for (i=1;i<=n;i++)
102         for (j=1;j<=m;j++)
103             scanf("%lld",&a[i][j]);
104 
105     build(1,1,n,1,m);
106     while (q--)
107     {
108         scanf("%d%d%d%d%d",&mode,&x1,&y1,&x2,&y2);
109         if (mode==1)
110             printf("%lld\n",query(1,1,n,1,m,x1,x2,y1,y2));
111         else
112         {
113             scanf("%d",&v);
114             update(1,1,n,1,m,x1,x2,y1,y2,v);
115         }
116     }
117     return 0;
118 }

 

posted @ 2019-05-29 19:04  congmingyige  阅读(222)  评论(0编辑  收藏  举报