1.题目大意。给定一个大小为s的矩阵,初始值全是0,然后两种操作,1:(x,y,val)在(x,y)这个点的值加上val。2:(l,r,x,y)询问以(l,r)为左上角,(x,y)为右下角这个矩阵里面所有值的和。
2.一个二维树状数组的裸题。二位树状数组其实就是一维树状数组的推广,对于每一行,我们用一个树状数组维护一下,然后再用一个数组维护一下所有的行。当然列也是一样的。这只是一个点修改,区间查询,对于区间修改点查询,我们可以使用二维差分,区间修改,区间查询,就是二维查分的二维前缀和。和一维数组都是一样的。
#include<iostream>
#include<cstdio>
#include<stdio.h>
#include<cstring>
using namespace std;
const int N = 1050;
int num[N][N];
#pragma warning(disable:4996)
int s;
void add(int x, int y, int val)
{
for (int i = x; i <= s; i += (i&(-i)))
{
for (int j = y; j <= s; j += (j&(-j)))
{
num[i][j] += val;
}
}
}
int query(int x, int y)
{
int ans = 0;
for (int i = x; i > 0; i-=(i&(-i)))
{
for (int j = y; j > 0; j -= (j&(-j)))
{
ans+=num[i][j];
}
}
return ans;
}
int main()
{
int t, q, x, y, sum, l, r, a;
scanf("%d%d", &t, &s);
memset(num, 0, sizeof(num));
while (scanf("%d", &q), q < 3)
{
if (q == 1)
{
scanf("%d%d%d", &x, &y, &a);
x++;
y++;
add(x, y, a);
}
else if (q == 2)
{
scanf("%d%d%d%d", &x, &y, &l, &r);
x++;
y++;
l++;
r++;
printf("%d\n", query(l, r) - query(l, y - 1) - query(x - 1, r) + query(x - 1, y - 1));
}
}
return 0;
}