二维线段树
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 }