zoukankan      html  css  js  c++  java
  • Matrix POJ

    题意:
    给定 n* n 矩阵A,其元素为0或1. A [ i ] [ j ] 表示第i行和第j列中的数字。最初全为0.
    我们有两个操作:

    1. C x1 y1 x2 y2(1 <= x1 <= x2 <= n,1 <= y1 <= y2 <= n)将左上角为(x1,y1),右下角为(x2,y2)的矩阵翻转(0变成1,1变成0)。
    2. Q x y(1 <= x,y <= n)查询A [ x ] [ y ],输出答案。

    分析:
    0 1 之间的反转可以考虑 “ ^ ” (异或),但这就需要二维线段树的延时标记了,那么有更好的方法吗?
    任意数字都可以通过 %2 得到 0 和 1 两个值;
    那么我们把矩阵反转改为矩阵所有元素 +1 ,(0+1)%2=1,(1+1)%2=0,0相当于偶数,1相当于奇数,最后询问的时候对答案%2,不就能把 0 1 相互转换改为了矩阵加法修改吗?(还需要用到差分思想,与前缀和思想类似)

    AC代码

    #include<cstdio>
    #include<cstring>
    #include<cctype>
    using namespace std;
    typedef long long LL;
    const int N=1e3+5;
    int sum[N][N],n,m;
    /// d[i][j]=a[i][j]-a[i-1][j]-a[i][j-1]+a[i-1][j-1]; (差分)
    /// a[i][j]=sum[i][j]-sum[i-1][j]-sum[i][j-1]+sum[i-1][j-1]; (前缀和)
    /// 由于是差分数组,既可以该减数也可以更改被减数来达到加值的目的,但为了保证所有下标大于1(lowbit!=0),则选择更改减数
    int lowbit(int x)
    {
        return x&(-x);
    }
    void update(int x,int y,int v)
    {
        for(int i=x;i<=n;i+=lowbit(i) )
            for(int j=y;j<=n;j+=lowbit(j) )
                sum[i][j]+=v;
    
    }
    void ran_up(int x1,int y1,int x2,int y2)
    {
        update(x1,y1,1);
        update(x2+1,y2+1,1);
        update(x1,y2+1,-1);
        update(x2+1,y1,-1);
    }
    int query(int x,int y)
    {
        int ret=0;
        for(int i=x;i>0;i-=lowbit(i) )
            for(int j=y;j>0;j-=lowbit(j) )
                ret+=sum[i][j];
        return ret&1;
    }
    inline void init()
    {
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                sum[i][j]=0;
    }
    int main()
    {
        int T,test=0;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d",&n,&m);
            init();
            if(test++) printf("
    ");
            while(m--)
            {
                char cmd[5];
                scanf("%s",cmd);
                if(cmd[0]=='C')
                {
                    int x1,x2,y1,y2;
                    scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
                    ran_up(x1,y1,x2,y2);
                }
                else
                {
                    int x,y;
                    scanf("%d%d",&x,&y);
                    printf("%d
    ",query(x,y) );
                }
            }
        }
        return 0;
    }

    总的来说是一道区间修改,单点查询的模板题

  • 相关阅读:
    QT事件(信号与槽)用法
    Debian自启动服务
    云锵投资 2020 年 09 月简报
    大数据表查询优化
    云锵投资 2020 年 08 月简报
    can't open ttyS0, error code 2
    QHostAddress 获取ip地址后 格式为"::ffff:127.0.0.1"问题
    qmake: could not exec '/home/hbg/Qt5.11.1/5.11.1/gcc_64/bin/qmake': No such file or directory
    connect to database error : Access denied for user 'root'@'localhost'
    ping 打印添加时间戳
  • 原文地址:https://www.cnblogs.com/DeepJay/p/12025215.html
Copyright © 2011-2022 走看看