zoukankan      html  css  js  c++  java
  • poj2155二维树状数组

    链接:http://poj.org/problem?id=2155

    题意:给一个矩阵,元素初始值都是0,对于一次修改操作,把要修改的矩阵中的0变为1,1变为0,给出要修改矩阵的左下角和右上角的位置。对于每个查询操作,输出矩阵某个位置上的值。

    思路:二维的树状数组,有个学习的链接:http://www.java3z.com/cwbwebhome/article/article1/1369.html?id=4804

    这道题要修改的是一个区间,求的是一个点,和最基本的树状数组不同。这里有个链接:http://hi.baidu.com/czyuan_acm/item/b14bff6ab6ffd093c5d249db 把树状数组的add()操作和sum()操作归一化了。挺好的。

    由于要求最后的值,可以有两个方案,一是统计翻转次数,还有一个是进行模拟。我这里是统计的翻牌次数。如果某个点被翻牌的次数为偶数,那么最后值为0,被翻的次数为奇数,最后值为1.

    先想一维的情况,要使区间(a,b)内的每个点的值都加d,那么区间(1,b)内点的值加d,区间(1,a-1)内点的值则要减d.

    对于二维的情况,修改范围(x1,y1)到(x2,y2),那么(x2,y2)加d,(x1-1,y2)和(x2,y1-1)减d,(x1-1,y1-1)要加d.

    由于这道题的翻牌的特性,如果某个区间我多翻了一次,那么我再翻一次就可以把上一次操作的影响抵消。所以就有了下面work()函数。

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    
    const int maxn=1000+5;
    int n,C[maxn][maxn];
    
    int lowbit(int x)
    {
        return x&(-x);
    }
    void update(int x,int y)
    {
        for(int i=x;i<=n;i+=lowbit(i))
            for(int j=y;j<=n;j+=lowbit(j))
                C[i][j]++;
    }
    void work(int x1,int y1,int x2,int y2)
    {
        x1++;y1++;x2++;y2++;
        update(x2,y2);
        update(x1-1,y2);
        update(x2,y1-1);
        update(x1-1,y1-1);
    }
    int query(int x,int y)
    {
        int s=0;
        for(int i=x;i>0;i-=lowbit(i))
            for(int j=y;j>0;j-=lowbit(j))
                s+=C[i][j];
        s=s%2;
        return s;
    }
    
    int main()
    {
    //    freopen("in.cpp","r",stdin);
        int t,q,x1,y1,x2,y2;
        char op[2];
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d",&n,&q);
            memset(C,0,sizeof(C));
            while(q--)
            {
                scanf("%s",&op);
                if(op[0]=='C')
                {
                    scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
                    work(x1,y1,x2,y2);
                }
                else
                {
                    scanf("%d%d",&x1,&y1);
                    printf("%d
    ",query(x1,y1));
                }
            }
            printf("
    ");
        }
        return 0;
    }
    View Code
  • 相关阅读:
    tab选项卡可自动播放
    鼠标跟随效果
    初识html5
    浅谈权限设计
    css表格撑大问题解决
    通用数据权限管理系统设计
    样式兼容IE7
    RBAC用户角色权限设计
    大话权限设计
    一个简易实用的web权限管理模块的应用与实现
  • 原文地址:https://www.cnblogs.com/54zyq/p/3301947.html
Copyright © 2011-2022 走看看