二维树状数组区间修改+区间查询模版

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cmath>
 5 using namespace std;
 6 int i,j,k,n,m,p,q,t1[2005][2005],t2[2005][2005],t3[2005][2005],t4[2005][2005];
 7 long long int x1,y,x2,y2;
 8 long long int lowbit(long long int p)
 9 {
10     return p & (-p);
11 }
12 void add(long long x,long long y,long long z)//单点修改 
13 {
14     for(int X = x;X <= n;X+= lowbit(X))
15     {
16         for(int Y = y;Y <= m;Y += lowbit(Y))
17         {
18             t1[X][Y] += z;
19             t2[X][Y] += z * x;
20             t3[X][Y] += z * y;
21             t4[X][Y] += z * x * y;
22         }
23     }
24 }
25 void qiuhe(long long int x1,long long int y,long long int x2,long long int y2,int z)//区间修改 
26 {
27     add(x1,y,z);
28     add(x1,y2 + 1,-z);
29     add(x2 + 1,y,-z);
30     add(x2 + 1,y2 + 1,z);
31 }
32 long long int ask(long long int x,long long int y)//求前缀和 
33 {
34     long long int res = 0;
35     for(i = x;i > 0;i -= lowbit(i))
36     {
37         for(j = y;j > 0;j -= lowbit(j))
38         {
39             res  += (x + 1) * (y + 1) * t1[i][j] - (y + 1) * t2[i][j] - (x + 1) * t3[i][j] + t4[i][j]; 
40         }
41     }
42     return res;
43  } 
44 long long int daan(long long int x1,long long int y,long long int x2,long long int y2)//求解 
45 {
46     return ask(x2,y2) - ask(x1-1,y2) - ask(x2,y-1) + ask(x1 - 1,y - 1);
47 }
48 int main()
49 {
50     scanf("%d %d %d %d",&n,&m,&p,&q);
51     for(i = 1;i <= p;i++) 
52     {
53         scanf("%d %d %d %d",&x1,&y,&x2,&y2);
54         qiuhe(x1,y,x2,y2,1);
55     }
56     for(int t = 1;t <= q;t++)
57     {
58         scanf("%d %d %d %d",&x1,&y,&x2,&y2);
59         printf("%lld
",daan(x1,y,x2,y2));
60     }
61     return 0;
62 }
原文地址:https://www.cnblogs.com/rax-/p/9850118.html