poj 2155 Matrix (二维树状数组)

来源:互联网 发布:淘宝商品怎么看配料表 编辑:程序博客网 时间:2024/05/19 19:57

题意:

一个初始为0的n*n矩阵,有m个操作,c为区间取反,q为单点查询


解题思路:

对于区间更新单点查询的题目,用树状数组是极好的,更新区间(a,b)我们update(a, 1), update(b+1, -1),然后查询的时候直接输出query(x)就是单点的值。

这个题需要扩展到二维,其实解法类似,    update(x1, y1, 1); update(x2+1, y1, -1);update(x1, y2+1, -1);update(x2+1, y2+1, 1); 就可以。

这个题的操作由于是取反,不是简单的加减,所以需要转换一下,我们记录取反的次数,最后每个点取反了奇数次就是1,取反了偶数次就是0。


代码:

#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#include <iostream>using namespace std;int bit[1005][1005];int n;int lowbit(int x){    return -x&x;}void update(int x, int y, int z){    int i, j;    for(i=x; i<=n; i+=lowbit(i))    {        for(j=y; j<=n; j+=lowbit(j))        {            bit[i][j]+=z;//            printf("%d %d\n", i, j);        }    }    return;}int query(int x, int y){    int res=0, i, j;    for(i=x; i>0; i-=lowbit(i))    {        for(j=y; j>0; j-=lowbit(j))        {            res+=bit[i][j];         }    }    return res;}int main(){    int i, j, t, m;    char x;    cin>>t;    while(t--)    {                scanf("%d%d", &n, &m);        for(i=0; i<=n; i++)for(j=0; j<=i; j++)bit[i][j]=bit[j][i]=0;        for(i=0; i<m; i++)        {           scanf("\n%c",  &x);            int sum=0,x1, y1, x2, y2;            if(x=='C')           {                            scanf("%d%d%d%d", &x1, &y1, &x2, &y2);              if(x1>x2 ||(x1==x2 && y1>y2))              {                    swap(x1, x2);                    swap(y1, y2);              }//              printf("%d %d %d %d\n", 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            {               scanf("%d%d", &x1, &y1);//               printf("%d\n", query(x1, y1));                printf("%d\n", query(x1, y1)&1);           }        }        if(t)printf("\n");    }   }


0 0