二维树状数组

Given an N*N matrix A, whose elements are either 0 or 1. A[i, j] means the number in the i-th row and j-th column. Initially we have A[i, j] = 0 (1 <= i, j <= N).

We can change the matrix in the following way. Given a rectangle whose upper-left corner is (x1, y1) and lower-right corner is (x2, y2), we change all the elements in the rectangle by using "not" operation (if it is a '0' then change it into '1' otherwise change it into '0'). To maintain the information of the matrix, you are asked to write a program to receive and execute two kinds of instructions.

1. C x1 y1 x2 y2 (1 <= x1 <= x2 <= n, 1 <= y1 <= y2 <= n) changes the matrix by using the rectangle whose upper-left corner is (x1, y1) and lower-right corner is (x2, y2).
2. Q x y (1 <= x, y <= n) querys A[x, y].
Input
The first line of the input is an integer X (X <= 10) representing the number of test cases. The following X blocks each represents a test case.

The first line of each block contains two numbers N and T (2 <= N <= 1000, 1 <= T <= 50000) representing the size of the matrix and the number of the instructions. The following T lines each represents an instruction having the format "Q x y" or "C x1 y1 x2 y2", which has been described above.
Output
For each querying output one line, which has an integer representing A[x, y].

There is a blank line between every two continuous test cases.
Sample Input
1
2 10
C 2 1 2 2
Q 2 2
C 2 1 2 1
Q 1 1
C 1 1 2 1
C 1 2 1 2
C 1 1 2 2
Q 1 1
C 1 1 2 1
Q 2 1
Sample Output
1
0
0
1

题意 : 给你一个矩阵,每次可以修改一个子矩阵,将 0 变成 1, 将 1 变成 0, 然后再给你一些询问,询问具体的某个位置的值是 0 还是 1
思路分析 : 首先某个位置的值只要看其修改的次数就可以,修改奇数次为 1, 偶数次 为 0

我们都知道,树状数组向上更新可以实现单点更新,向下可以实现区间查询,在这里,我们通过一个转换,就可以实现区间更新,单点查询了。
在一维的情况下,我们如果想要将区间 [a, b] 的值都加上 val , 那么就可以让区间 [1, b] 的值都加上 val , 再让 [1, a-1] 的值都减去 val 即可,最后查询某个点的值就只需要
向上统计它全部的父节点的就可以了。

代码示例 :
#define ll long long
const int maxn = 1e6+5;
const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f;

int n, m;
int c[1005][1005];
int a1, b1, a2, b2;

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

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

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

int main() {
    //freopen("in.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
    int t;
    char s[5];
    
    cin >> t;
    while(t--){
        cin >> n >> m;
        memset(c, 0, sizeof(c));
        for(int i = 1; i <= m; i++){
            scanf("%s", s);
            if (s[0] == 'C'){
                scanf("%d%d%d%d", &a1, &b1, &a2, &b2);
                update(a2, b2, 1);
                update(a1-1, b1-1, 1);
                update(a1-1, b2, -1);
                update(a2, b1-1, -1);
            }
            else {
                scanf("%d%d", &a1, &b1);
                int f = sum(a1, b1);
                if (f&1) printf("1\n");
                else printf("0\n");
            }
        }
        printf("\n");        
    }
    return 0;
}

 

posted @ 2018-04-09 19:24  楼主好菜啊  阅读(321)  评论(0编辑  收藏  举报