zoukankan      html  css  js  c++  java
  • POJ 2155 Matrix (二维树状数组)题解

    思路:

    没想到二维树状数组和一维的比只差了一行,update单点更新,query求和

    这里的函数用法和平时不一样,query直接算出来就是某点的值,怎么做到的呢?

    我们在更新的时候不止更新一个点,而是四个点,这样就会变成下图这样的效果

    看不懂听我讲一下...这和上次嘉诚讲过的差分数组有点像(自觉回顾讲过什么),既然单点更新更新完是(1,1)~(x,y)的和在改变,那么我们只要在区间后面减去增加的,那么我们一算求和就等于求这个点的值了。我们要更新的实际上是黑框内区域,但是我们只更新(x1,y1)就只更新了红框区域,所以更新时多出来的三个点就是绿色的三块区域,因为是翻转问题,所以翻偶数次就是等于没翻,可以看到,最后绿色区域算上叠加都翻了偶数次,所以就抵消了。

    代码:

    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define ll long long
    using namespace std;
    const int N = 1000+5;
    int bit[N][N],n;
    int lowbit(int x){
        return x&(-x);
    }
    void update(int a,int b){
        for(int i = a;i <= n;i += lowbit(i)){
            for(int j = b;j <= n;j += lowbit((j))){
                bit[i][j]++;
            }
        }
    }
    int query(int a,int b){
        int ret = 0;
        for(int i = a;i > 0;i -= lowbit(i)){
            for(int j = b;j > 0;j -= lowbit(j)){
                ret += bit[i][j];
            }
        }
        return ret;
    }
    int main(){
        int T,q,a,b,c,d;
        char o[2];
        scanf("%d",&T);
        while(T--){
            memset(bit,0,sizeof(bit));
            scanf("%d%d",&n,&q);
            for(int i = 0;i < q;i++){
                scanf("%s",o);
                if(o[0] == 'Q'){
                    scanf("%d%d",&a,&b);
                    printf("%d
    ",(query(a,b) - ) % 2);
                }
                else{
                    scanf("%d%d%d%d",&a,&b,&c,&d);
                    update(a,b);
                    update(c+1,b);
                    update(a,d+1);
                    update(c+1,d+1);
                }
            }
            if(T) printf("
    ");
        }
        return 0;
    }
    


  • 相关阅读:
    13-02 Java 数组高级算法,Arrays类
    从0移植uboot (二) _uboot启动流程分析
    Linux input子系统编程、分析与模板
    跟着内核学框架-从misc子系统到3+2+1设备识别驱动框架
    Linux驱动技术(八) _并发控制技术
    Linux驱动技术(七) _内核定时器与延迟工作
    Linux驱动技术(六) _内核中断
    Linux驱动技术(五) _设备阻塞/非阻塞读写
    Linux驱动技术(四) _异步通知技术
    Linux驱动技术(三) _DMA编程
  • 原文地址:https://www.cnblogs.com/KirinSB/p/9408786.html
Copyright © 2011-2022 走看看