【POJ 1195】二维树状数组

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;
}

猜你喜欢

转载自blog.csdn.net/weixin_41863129/article/details/89526418