poj 2155 Matrix (二维树状数组)

题意:给你一个矩阵开始全是0,然后给你两种指令,第一种:C x1,y1,x2,y2 就是将左上角为x1,y1,右下角为x2,y2,的这个矩阵内的数字全部翻转,0变1,1变0 第二种:Q x1 y1,输出举证x1,y1,位置的数值

思路:该题的巧妙之处是反转的重叠抵消,记住要向上统计,向下修改;二维情况,最主要的是理解那个数组中的每个点保存的值的意义(一个矩形区域的总和);最后记住取余;

此题参考博客 http://blog.csdn.net/xymscau/article/details/6601298

树状数组参考博客 http://www.cnblogs.com/zhangshu/archive/2011/08/16/2141396.html

特别好的树状数组讲解 http://www.topcoder.com/tc?module=Static&d1=tutorials&d2=binaryIndexedTrees#prob

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#define maxn 1005
using namespace std;

int tree[maxn*2][maxn*2];
int n;

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

int getnum(int x,int y)
{
    int ans=0;
    for(int i=x;i>0;i-=lowbit(i))
        for(int j=y;j>0;j-=lowbit(j))
        {
            ans+=tree[i][j];
        }
        return ans;
}

void updata(int x,int y,int val)
{
    for(int i=x;i<=n;i+=lowbit(i))
     for(int j=y;j<=n;j+=lowbit(j))
      tree[i][j]+=val;
}

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int k;
        scanf("%d %d",&n,&k);
        getchar();
        memset(tree,0,sizeof(tree));
        while(k--)
        {
            char str;
            scanf("%c",&str);
            if(str=='Q')
            {
                int x,y;
                scanf("%d %d",&x,&y);
                getchar();
                cout<<getnum(x,y)%2<<endl;
            }
            else
            {
                int x1,y1,x2,y2;
                scanf("%d %d %d %d",&x1,&y1,&x2,&y2);
                getchar();
                updata(x1,y1,1);
                updata(x1,y2+1,1);
                updata(x2+1,y1,1);
                updata(x2+1,y2+1,1);
            }
        }
        cout<<endl;
    }
    return 0;
}
原文地址:https://www.cnblogs.com/simplekinght/p/6612965.html