POJ 2155 Matrix(二维树状数组)

来源:互联网 发布:辐射4xboxonex优化 编辑:程序博客网 时间:2024/05/28 17:07


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


题意:操作C表示让左上角为(x1,y1)右下角为(x2,y2)的矩形内所有的01取反,一开始的时候全部为0。Q询问(x,y)内是0还是1。


这道题可以把01取反看成是操作C的累加,如果某个单元被操作了奇数次,那么相当于取反,否则就是没有动。这道题和一维情况中改变区间查询点的情况类似,只是将一维升级成二维。如果现在要改变左上角为(x1,y1)右下角为(x2,y2)的矩形,那么只要给一个二维数组中(x1,y1)(x2+1,y2+1)(x1,y2+1)(x1+1,y2)全部加上1,以(x1,y1)为例,在查询(x,y)的时候,通过累加,会把以(1,1)为左上角,(x,y)为右下角的矩形中所有的数加起来,那么如果(x1,y1)在这范围内,对(x,y)而言,就被操作了一次。综合起来,就是把以(x1,y1)为左上角,(n,n)为右下角的矩形内01取反。同理,其他也是一样的。最后相互抵消后,相当于是让左上角为(x1,y1)右下角为(x2,y2)的矩形内所有的01取反。



#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#define N 1005using namespace std;int n;char s[3];int c[N][N];int lowbit(int x){    return x&(-x);}void change(int x, int y, int d){    int i = y;    while(x <= n)    {        y = i;        while(y <= n)        {            c[x][y] += d;            c[x][y] %= 2;            y += lowbit(y);        }        x += lowbit(x);    }}int query(int x, int y){    int i = y, sum = 0;    while(x > 0)    {        y = i;        while(y > 0)        {            sum += c[x][y];            sum %= 2;            y -= lowbit(y);        }        x -= lowbit(x);    }    return sum;}int main(){    int T, m, ans, x, y, x2, y2, x1, y1;    scanf("%d", &T);    while (T--)    {        scanf("%d%d", &n, &m);        memset(c, 0, sizeof(c));        for (int i = 1; i <= m; i++)        {            scanf("%s", &s);            if (s[0] == 'C')            {                scanf("%d%d%d%d", &x1, &y1, &x2, &y2);                change(x2+1, y2+1, 1);                change(x1, y2+1, 1);                change(x2+1, y1, 1);                change(x1, y1, 1);            }            if (s[0] == 'Q')            {                scanf("%d%d", &x, &y);                ans = query(x, y);                printf("%d\n", ans);            }        }        if (T) printf("\n");    }    return 0;}

0 0
原创粉丝点击