POJ-1195 Mobile phones---裸的二维树状数组(注意下标从1,1开始)

题目链接:

https://vjudge.net/problem/POJ-1195

题目大意:

直接维护二维树状数组

注意横纵坐标全部需要加1,因为树状数组从(1,1)开始

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<string>
 6 #include<cmath>
 7 #include<set>
 8 #include<queue>
 9 #include<map>
10 #include<stack>
11 #include<vector>
12 #include<list>
13 #include<deque>
14 #include<sstream>
15 #include<cctype>
16 #define REP(i, n) for(int i = 0; i < (n); i++)
17 #define FOR(i, s, t) for(int i = (s); i < (t); i++)
18 using namespace std;
19 typedef long long ll;
20 int T, n, m, cases;
21 int num[1048][1048];
22 int lowbit(int x)
23 {
24     return x & (-x);
25 }
26 ///修改num[x][y] = d
27 void add(int x, int y, int d)
28 {
29     for(int i = x; i <= n; i += lowbit(i))
30     {
31         for(int j = y; j <= n; j += lowbit(j))
32             num[i][j] += d;
33     }
34 }
35 ///计算顶点为(1, 1)(x, y)的数总和
36 int sum(int x, int y)
37 {
38     int ans = 0;
39     for(int i = x; i > 0; i -= lowbit(i))
40     {
41         for(int j = y; j > 0; j -= lowbit(j))
42             ans += num[i][j];
43     }
44     return ans;
45 }
46 int main()
47 {
48     int t, x1, y1, x2, y2, d;
49     while(cin >> t >> n)
50     {
51         memset(num, 0, sizeof(num));
52         while(cin >> t)
53         {
54             if(t == 3)break;
55             else if(t == 1)
56             {
57                 scanf("%d%d%d", &x1, &y1, &d);
58                 x1++, y1++;
59                 add(x1, y1, d);
60             }
61             else if(t == 2)
62             {
63                 scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
64                 x1++, y1++, x2++, y2++;
65                 cout<<(sum(x2, y2) - sum(x2, y1 - 1) - sum(x1 - 1, y2) + sum(x1 - 1, y1 - 1))<<endl;
66             }
67         }
68     }
69     return 0;
70 }
原文地址:https://www.cnblogs.com/fzl194/p/8934156.html