SPOJ

题目链接:

https://vjudge.net/problem/SPOJ-MATSUM

题目大意:

二维数组,两种操作

SET 将某点设置成x

SUM 求某个区域之和

解题思路:

这里用二维树状数组

SUM可以直接求出来

这里将某点设置成x,和树状数组不同,树状数组是讲某点加上一个值,但是可以另外建一个数组存储当前所有点的数值,如果要将(x, y)设置成d的话,可以先把该点减去a[x][y]再加上d

合并一下就是:add(x, y, d - a[x][y])

 1 #include<iostream>
 2 #include<string>
 3 #include<cstdio>
 4 #include<cstring>
 5 using namespace std;
 6 typedef long long ll;
 7 const int maxn = 1025;
 8 int tree[maxn][maxn];
 9 int a[maxn][maxn];//记录当前每个位置的值
10 int n;
11 int lowbit(int x)
12 {
13     return x & (-x);
14 }
15 //修改tree[x][y] += d;
16 void add(int x, int y, int d)
17 {
18     for(int i = x; i <= n; i += lowbit(i))
19     {
20         for(int j = y; j <= n; j += lowbit(j))
21         {
22             tree[i][j] += d;
23         }
24     }
25 }
26 //从(1,1)到(x, y)数字之和
27 ll sum(int x, int y)
28 {
29     ll ans = 0;
30     for(int i = x; i > 0; i -= lowbit(i))//等于0会无限循环
31     {
32         for(int j = y; j > 0; j -= lowbit(j))
33         {
34             ans += tree[i][j];
35         }
36     }
37     return ans;
38 }
39 
40 int main()
41 {
42     int T;
43     scanf("%d", &T);
44     while(T--)
45     {
46         scanf("%d", &n);
47         memset(tree, 0, sizeof(tree));
48         memset(a, 0,sizeof(a));
49         char s[5];
50         int x, y, z, x1, y1, x2, y2;
51         while(scanf("%s", s))
52         {
53             if(s[0] == 'E')break;
54             if(s[1] == 'E')//SET
55             {
56                 scanf("%d%d%d", &x, &y, &z);
57                 x++;
58                 y++;//必须从(1,1)开始
59                 add(x, y, z - a[x][y]);//利用之前该位置的数值,就可以把该点设置成z
60                 a[x][y] = z;
61             }
62             else if(s[1] == 'U')//SUM
63             {
64                 scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
65                 x1++, y1++, x2++, y2++;
66                 ll ans = 0;
67                 ans += sum(x2, y2);
68                 ans += sum(x1 - 1, y1 - 1);
69                 ans -= sum(x1 - 1, y2);
70                 ans -= sum(x2, y1 - 1);
71                 printf("%lld
", ans);
72             }
73         }
74     }
75     return 0;
76 }
原文地址:https://www.cnblogs.com/fzl194/p/8923153.html