poj 2155 (二维数组)

来源:互联网 发布:银行家算法实现 编辑:程序博客网 时间:2024/04/27 18:03
这题是比较经典的二维树状数组,题意是给你个矩阵里面开始全是0,然后给你两种指令:1:‘C x1,y1,x2,y2’就是将左上角为x1,y1,右下角为x2,y2,的这个矩阵内的数字全部翻转,0变1,1变0,;2:'Q x1 y1',输出a[x1][y1]的值。这题的巧妙只初在于重叠消元,将要翻转的矩阵的四个角更新一遍就ok了,去掉重叠部分(结果模2),刚好剩下了这个矩阵翻转了.
#include <cstdio>#include <iostream>#include <cstring>#include <string>#include <cstdlib>#include <algorithm>#include <cmath>#include <set>#include <list>#include <queue>using namespace std;#define L(i) i<<1#define R(i) i<<1|1#define INF 0x3f3f3f3f#define pi acos(-1.0)const int N = 100005;const double eps = 1e-10;int c[1010][1010],n,m;void update(int x,int y,int val){    for(int i = x; i <= n; i+=i&(-i))        for(int j = y; j <= n; j+=j&(-j))            c[i][j] += val;}int getsum(int x,int y){    int s = 0;    for(int i = x; i > 0; i-=i&(-i))        for(int j = y; j > 0; j-=j&(-j))            s += c[i][j];    return s;}int main(){    int t;    scanf("%d",&t);    while(t--)    {        scanf("%d%d",&n,&m);        memset(c, 0, sizeof(c));        while(m--)        {            getchar();            char ch;            scanf("%c",&ch);            if(ch == 'C')            {                int x1,x2,y1,y2;                scanf("%d%d%d%d",&x1,&y1,&x2,&y2);                update(x1,y1,1);                update(x2+1,y1,1);                update(x1,y2+1,1);                update(x2+1,y2+1,1);            }            else            {                int x,y;                scanf("%d%d",&x,&y);                printf("%d\n",getsum(x,y)%2);            }        }        printf("\n");    }    return 0;}


0 0
原创粉丝点击