POJ 2155 Matrix (二维树状数组)

来源:互联网 发布:js路由重置 编辑:程序博客网 时间:2024/05/07 08:43

题意:

提供一个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;}


原创粉丝点击