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


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