题目链接:
题目大意:
二维数组,两种操作
SET 将某点设置成x
SUM 求某个区域之和
解题思路:
这里用
SUM可以直接求出来
这里将某点设置成x,和树状数组不同,树状数组是讲某点加上一个值,但是可以另外建一个数组存储当前所有点的数值,如果要将(x, y)设置成d的话,可以先把该点减去a[x][y]再加上d
合并一下就是:add(x, y, d - a[x][y])
1 #include2 #include 3 #include 4 #include 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')//SET55 {56 scanf("%d%d%d", &x, &y, &z);57 x++;58 y++;//必须从(1,1)开始59 add(x, y, z - a[x][y]);//利用之前该位置的数值,就可以把该点设置成z60 a[x][y] = z;61 }62 else if(s[1] == 'U')//SUM63 {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\n", ans);72 }73 }74 }75 return 0;76 }