您的位置:首页 > 其它

POJ 2155 Matrix (二维树状数组)

2013-08-26 19:40 429 查看
题意:

提供一个N*N 的矩阵,其中每一个格子中的数不是1 就是0,初始时每一个格子的值为0,我们可以修改这个矩阵中的数字,每次给出矩阵的左上角坐标(x1,y1),以及右下角的坐标(x2, y2),并且将矩阵中的数字全部取反(原来是1 现在变成0,原来是0 现在变成1),还可以每次查询第x 行第y 列的格子中的数字是什么。

分析:此题是一般树状数组题目的倒转思维,一般会单点更新,区间求和...............虽然这题看上去是区间更新,单点求和,但是转换一下就是普通的单点更新,区间求和了。

a[i]为该点的改变次数,退化成一维的(x,y)区间,可以等价于起点a[x] + 1,终止点a[y+1] - 1,这样单点更新,总体求和是不变的,而改变了的区间求和是有变化的。所以求和对二取模就知道最后为0还是1了....................................

#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <vector>
#include <set>
#include <queue>
#include <stack>
#include <climits>//形如INT_MAX一类的
#define MAX 1111
#define INF 0x7FFFFFFF
#define REP(i,s,t) for(int i=(s);i<=(t);++i)
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a))
#define mp(a,b) make_pair(a,b)
#define L(x) x<<1
#define R(x) x<<1|1
# define eps 1e-5
//#pragma comment(linker, "/STACK:36777216") ///传说中的外挂
using namespace std;

int c[MAX][MAX];
char op;
int n,T,q;

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

void update(int x,int y,int va) {
for(int i=x; i<=n; i += lowbit(i)) {
for(int j=y; j<=n; j += lowbit(j)) {
c[i][j] += va;
}
}
}

int query(int x,int y) {
int sum = 0;
for(int i=x; i>0; i -= lowbit(i)) {
for(int j=y; j>0; 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,&q);
memset(c,0,sizeof(c));
for(int i=0; i<q; i++) {
getchar();
scanf("%c",&op);
if(op == 'C') {
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
update(x2+1,y2+1,1);
update(x2+1,y1,-1);
update(x1,y2+1,-1);
update(x1,y1,1);
}
if(op == 'Q') {
scanf("%d%d",&x1,&y1);
printf("%d\n",query(x1,y1) % 2);
}
}
if(T != 0)
puts("");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: