POJ2155 - Matrix

题目大意

给定一个大小为N*N的矩阵,每个元素要么为0要么为1,刚开始时A[i][j]=0,(1<=i,j<=N)

每次给出矩阵的左下角坐标(x1,y1)和右上坐标(x2,y2),将矩阵中的所有数组取反,或者给出一个坐标(x,y),要求你查询A[x][y]的值是多少。

题解

查询一个点和修改一个区间,这刚好是树状数组的可以实现的功能

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#define MAXN 1005
using namespace std;
int c[MAXN][MAXN];
int n;
int lowbit(int x)
{
    return x&-x;
}
int sum(int x,int y)
{
    int i,j,ret=0;
   for(i=x;i>0;i-=lowbit(i))
   for(j=y;j>0;j-=lowbit(j))
   ret+=c[i][j];
   return ret;
}
void add(int x,int y,int d)
{
    int i,j;
        for(i=x;i<=n;i+=lowbit(i))
        for(j=y;j<=n;j+=lowbit(j))
        c[i][j]+=d;
}
int main(void)
{
    char ch;
    int m,T,x1,y1,x2,y2,ans;
    cin>>T;
    while(T--)
    {
        scanf("%d%d",&n,&m);
        memset(c,0,sizeof(c));
        while(m--)
        {
            getchar();
            scanf("%c",&ch);
            if(ch=='C')
            {
                scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
                add(x1,y1,1);
                add(x2+1,y1,1);
                add(x1,y2+1,1);
                add(x2+1,y2+1,1);
            }
            else
            {
                scanf("%d%d",&x1,&y1);
                ans=sum(x1,y1)&1;
                printf("%d\n",ans);
            }
        }
        printf("\n");
    }
    return 0;
}

posted on 2013-04-19 22:51  仗剑奔走天涯  阅读(147)  评论(0编辑  收藏  举报

导航