POJ 2155 Matrix (二维树状数组)

题意:

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


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章