【数据结构】POJ - 2155 Matrix 题解

题意

给出一个n*n的01矩阵,一开始全是0,给出q个操作,一种是给出一个矩阵的左上角坐标和右下角坐标(题意定义左上为原点),将这个矩阵内的所有元素0变成1,1变成0,另一种操作是询问一个点是0还是1
其中n<=10^3 q<=5*10^4
多组测试数据,保证小于十组。

分析

用二维树状数组,修改时,设左上角(x1,y1),右上角(x2,y2),就在(x1,y1),(x2+1,y1),(x1,y2+1),(x2+1,y2+1)各加1,查询时直接求前缀和%2,即这个点和原点形成的矩形里元素的和。画图可以发现,对于每次修改,在矩形内的点求和时会加一,但是如果在矩形外的区域,就一定会加二的倍数(这是这道题比较巧妙的点),最后被%掉。

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#define MAXN 1006
using namespace std;
int bit[MAXN][MAXN],x1,y1,x2,y2,n,T,q;
char op;
inline int lowbit(int x)
{
    return x&(-x);
}
void change(int x,int y)
{
    for(;x<=n;x+=lowbit(x))
        for(int i=y;i<=n;i+=lowbit(i))
            bit[x][i]++;
}
int addup(int x,int y)
{
    int re=0;
    for(;x;x-=lowbit(x))
        for(int i=y;i;i-=lowbit(i))
            re+=bit[x][i];
    return re;
}
int main()
{
    scanf("%d",&T);
    while(T--)
    {
        memset(bit,0,sizeof(bit));
        scanf("%d%d",&n,&q);
        for(int i=1;i<=q;i++)
        {
            scanf("\n%c",&op);
            if(op=='C')
            {
                scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
                change(x1,y1);
                change(x2+1,y1);
                change(x2+1,y2+1);
                change(x1,y2+1);
            }
            else
            {
                scanf("%d%d",&x1,&y1);
                printf("%d\n",addup(x1,y1)%2);
            }
        }
        if(T) printf("\n");
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值