Two-dimensional segment tree

 

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      /// should be careful, not in the order of two-dimensional read 
18 is      IF (XL YL && == == XR YR )
 . 19          SUM [IND] = A [XL] [YL];
 20 is      the else 
21 is      {
 22 is          int XM = (XR + XL) >> . 1 ;
 23 is          int YM = (YR + YL) >> . 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 [In * 4 + 2 ] + = roof [into] * (XR-xm) * (YM-yl + 1 );
43      sum [In * 4 + 3 ] + = roof [into] * (XR-xm) * (YR ym);
44  
45      get [In * 4 ] + = roof [In];
46      get [In * 4 + 1 ] + = roof [In];
47      get [In * 4 + 2 ] + = roof [In];
48      get [In * 4 + 3 ] + = roof [In];
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<         tot + = query (In *92yr)
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 }

 

Guess you like

Origin www.cnblogs.com/cmyg/p/10945636.html