POJ 2155 Matrix(二维树状数组+二维差分)

题目链接
题目大意:起初一个全0矩阵,q个操作,可以修改(x1,y1)到(x2,y2)这个子矩阵,让其中元素翻转(0变1,1变0),每次询问单点a[x1][y1]的信息。
思路:碰到这种区间修改的第一反应就是线段树和差分数组,但二维线段树让谁打谁都不想打,代码不少,那就为了方便调试只能差分数组了。
我觉得这篇博客讲的不错,二维差分不想画图理解的话就看这个把。博客地址

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const int N=1e3+10;
int c[N][N],n,q;
inline int lowbit(int x){
    
    return x&(-x);}
void add(int x,int y,int val)
{
    
    
    int yy=y;
    while(x<=n)
    {
    
    
        yy=y;
        while(yy<=n)
        {
    
    
            c[x][yy]+=val;
            yy+=lowbit(yy);
        }
        x+=lowbit(x);
    }
}
int query(int x,int y)
{
    
    
    int res=0,yy=y;
    while(x>0)
    {
    
    
        yy=y;
        while(yy>0)
        {
    
    
            res+=c[x][yy];
            yy-=lowbit(yy);
        }
        x-=lowbit(x);
    }
    return res;
}
int main()
{
    
    
    int t;
    scanf("%d",&t);
    while(t--)
    {
    
    
        memset(c,0,sizeof(c));
        scanf("%d%d",&n,&q);
        char op[5];
        int x1,x2,y1,y2;
        for(int i=1;i<=q;i++)
        {
    
    
            scanf("%s",op);
            if(op[0]=='C')
            {
    
    
                scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
                add(x1,y1,1);
                add(x2+1,y2+1,1);
                add(x2+1,y1,-1);
                add(x1,y2+1,-1);
            }
            else
            {
    
    
                scanf("%d%d",&x1,&y1);
                printf("%d\n",query(x1,y1)%2);
            }
        }
        printf("\n");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/amazingee/article/details/107670297