您的位置:首页 > 其它

poj2155 Matrix 二维树状数组

2017-06-26 14:37 225 查看
题意:一个01矩阵,进行两种操作,一种是对一个子矩阵的数字进行反转,0变1,1变0。还有一种是查询一个数字。

这里涉及频繁的区间修改和查询,可以考虑使用树状数组。

因为是一个矩阵,所以要拓展到二维。是区间修改和单点查询所以使用向下修改,向上统计。重点在于二维树状数组的add和getsum怎么写。

然后是因为getsum得到的都是从原点到对应点的一个矩阵的和,所以要得到一个子矩阵可以考虑使用4个从原点开始的矩阵进行加减得到对应的子矩阵。

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#include <queue>

#define LL long long int

using namespace std;

int T, N, M;
int c[1005][1005];
char s[3];

int lowbit(int x)
{
return x&(-x);
}

void add(int x, int y, int num)
{
for (int i = x; i > 0; i -= lowbit(i))
{
for (int j = y; j > 0; j -= lowbit(j))
{
c[i][j] += num;
}
}
}

int getsum(int x, int y)
{
int sum = 0;
for (int i = x; i <= N; i += lowbit(i))
{
for (int j = y; j <= N; j += lowbit(j))
{
sum += c[i][j];
}
}
return sum;
}

int main()
{
int x1, x2, y1, y2;
scanf("%d", &T);
while (T--)
{
scanf("%d%d", &N, &M);
for (int i = 1; i <= N; ++i)
{
for (int j = 1; j <= N; ++j)
{
c[i][j] = 0;
}
}
while (M--)
{
scanf("%s", s);
if (s[0] == 'C')
{
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
add(x1 - 1, y1 - 1, 1);
add(x2 , y2, 1);
add(x2, y1 - 1, -1);
add(x1 - 1, y2, -1);
}
else if (s[0] == 'Q')
{
scanf("%d%d", &x1, &y1);
printf("%d\n", getsum(x1, y1) & 2);
}
}
printf("\n");
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: