• 二维树状数组


    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
    ");
                    else printf("0
    ");
                }
            }
            printf("
    ");        
        }
        return 0;
    }
    
    东北日出西边雨 道是无情却有情
  • 相关阅读:
    C#学习第四弹之封装、继承和多态
    C#学习第三弹之给常量赋值可能引发的问题
    C#学习第二弹之C#与.NET框架
    hdu 5199 map或二分或哈希
    hdu 5195 线段树
    hdu 2545 并查集
    ACM数论模板
    C#学习第一弹之Hello World
    对字符串进行频繁拼接的话,使用StringBuffer或者StringBuilder
    String中根据,(逗号)进行分割
  • 原文地址:https://www.cnblogs.com/ccut-ry/p/8762246.html
Copyright © 2020-2023  润新知