您的位置:首页 > 其它

poj2155(二维树状数组)

2014-08-05 09:26 134 查看
学习链接:http://www.java3z.com/cwbwebhome/article/article1/1369.html?id=4804

题意:一个n*n的矩阵,两种操作,更新以A[x1,y1]为左上角,A[x2,y2]为右下角的矩阵,查询A[i,j]点的值

思路:二维树状数组好题,就查询操作而言,只要知道那个点的翻转次数的奇偶性就可以了,所以每次操作我们只需要更新四个点,然后求(1,1)到该点的sum

然后就可知道他的奇偶性了,至于更新哪四个点自己画个图感觉下就可以了

代码如下:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<stdio.h>
#include<stdlib.h>
#include<math.h>

#define inf 0x7ffffff
#define eps 1e-9
#define N 1005
#define pi acos(-1.0)
using namespace std;
int flag

,c

;
int lowbit(int x)
{
    return x&(-x);
}
void update(int x,int y)
{
    flag[x][y] = flag[x][y] == -1 ? 1 : -1;
    int i,j;
    for(i = x; i <= 1000; i+=lowbit(i))
        for(j = y; j <= 1000; j+=lowbit(j))
            c[i][j] += flag[x][y];
}
int sum(int x,int y)
{
    int i,j;
    int res = 0;
    for(i = x; i > 0; i-=lowbit(i))
        for(j = y; j > 0; j-=lowbit(j))
            res += c[i][j];
    return res;
}

int main()
{
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
    int t;
    scanf("%d",&t);
    while(t--)
    {
        memset(flag,-1,sizeof(flag));
        memset(c,0,sizeof(c));
        int n,m;
        scanf("%d%d",&n,&m);
        while(m--)
        {
            char str[2];
            int x1,y1,x2,y2;
            scanf("%s",str);
            if(*str == 'C'){
                scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
                update(x1,y1);
                update(x2+1,y2+1);
                update(x1,y2+1);
                update(x2+1,y1);
            }
            else {
                scanf("%d%d",&x1,&y1);
                printf("%d\n",sum(x1,y1)%2);
            }
        }
        if(t)
            printf("\n");
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: