POJ 2155 Matrix 树状数组

原创 2013年12月04日 16:47:12

题目大意:

给定一N*N的矩阵,每个元素为1或0,初始全为0,有如下两种操作

(1)将某一个矩形区域内的所有元素取反,即1改为0,0改为1

(2)询问某一个元素的值,输出0或1

首先不难看出,因为只有01所以与其取反,不如给区间中的某个元素都+1,和开关灯问题的性质相同,最后模2即可;

查询某个点的当前的值,可以转化为查询当前所有的操作中有多少个操作区间包含所查询点(因为每个操作都是给区间中的每个元素+1嘛);

一个区间可以用对角线上的两个顶点表示,如果一个点在这个区间中,那么从矩阵(0,0)位置到该点做组成的矩阵一定包含且只包含一个顶点;

但是这样的话无法区分矩阵外面的点,如果用四个顶点表示这个矩阵呢?这时,矩阵内点所围的矩阵包含一个顶点,而矩阵外的点所围的矩阵包含0、2或4个顶点,模2恰好为0,这样就能通过从(0,0)到某点矩阵所包含的顶点数来完成矩阵内外点的区分了

再由叠加的性质,通过计算顶点数的和可以在模2的意义下区分查询点点被多少个矩阵所围

于是问题就转化为了:以(0,0)和所询问点(x,y)所围成的矩形中包含多少顶点,即子矩阵矩阵元素和是多少?每插入一个矩形,就将其四个顶点插入树状数组,查询时,即求给定区间内的元素和,解决~


关于树状数组:

树状数组是什么?树状数组虽然描述起来是数组,但是表示其元素的关系上应该用类似树的形式画出

树状数组能做什么?最常用的目的:求某个区间的和,给定一个数组若求一段区间的和,我们可以通过预处理出每个“前缀”的和在查询时得到O(1)的复杂度,然而如果这个数组是动态的话,比如我们可以修改某个元素的值,再查询时如果不做预处理,修改O(1),查询需要整体求和O(n);如果预处理,查询O(n),修改需要修改所有包含这个元素的值O(n)。而树状数组就是在这两种状况的一个平衡,它所做的是“不完全”的预处理,将修改的一部分代价转移到查寻时来做,这样查寻和修改都是O(logn),效率较高

而树状数组扩展到高维也很容易,它不过是一个求和的预处理而已

顺便越发的觉得树状数组这个结构十分优美了,虽然所能做的比较有限,但是实现起来相当简单


下面是这道题的代码,注释不多,希望上面的文字描述大概就够了....

#include <cstdio>
#include <cstring>
#define MAXN 1010

int c[MAXN][MAXN];

int lowbit(int k)
{
    return k & -k;
}
void modify(int a, int b, int d)
{
    for (int i = a; i < MAXN; i += lowbit(i))
    {
        for (int j = b; j < MAXN; j += lowbit(j))
        {
            c[i][j] += d;
        }
    }
}
int check(int a, int b)
{
    int total = 0;
    for (int i = a; i > 0; i -= lowbit(i))
    {
        for (int j = b; j > 0; j -= lowbit(j))
        {
            total += c[i][j];
        }
    }
    return total;
}


int main()
{
    int caseSet, n , t;
    char str[3];
    int x1, y1, x2, y2;
    int tmp;
    scanf("%d", &caseSet);
    while (caseSet--)
    {
        scanf("%d %d", &n, &t);
        memset(c, 0, sizeof(c));

        while (t--)
        {
            scanf("%s", str);

            switch (str[0])
            {
            case 'C':
                scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
                x2++; y2++; // 这里注意顶点的设置应类似“左闭右开”的形式,否则查询边上的点的时候可能会出问题
                modify(x2, y2, 1);
                modify(x1, y2, 1);
                modify(x2, y1, 1);
                modify(x1, y1, 1);
                break;
            case 'Q':
                scanf("%d%d", &x1, &y1);
                tmp = check(x1, y1);
                printf("%d\n", tmp % 2);
                break;
            }

        }
        printf("\n");
    }
    return 0;
}


POJ2155:Matrix(二维树状数组,经典)

Description Given an N*N matrix A, whose elements are either 0 or 1. A[i, j] means the number in ...
  • libin56842
  • libin56842
  • 2015年06月24日 12:17
  • 2684

poj 2155 Matrix(二维树状数组)

楼教主出的二维树状数组。给出矩阵左上角和右下角坐标,矩阵里的元素 1变0 ,0 变1,然后给出询问,问某个点是多少。纠结好久了,一直没什么好思路,看discuss说四个角神马的,我搜了下,理解了,树状...
  • zxy_snow
  • zxy_snow
  • 2011年03月21日 10:34
  • 8793

Matrix.(POJ-2155)(树状数组)

一道二维树状数组的题目,比较经典,适合新手练习。 可以打印出来每次操作后矩阵的情况,就能很直观的理解这个树状数组是怎么实现的,他将多余的部分巧妙的重复了偶数次,使得多余部分奇偶不会发生变化。 #inc...
  • weizhuwyzc000
  • weizhuwyzc000
  • 2015年05月02日 22:09
  • 1007

POJ 2155 Matrix(二维树状数组,绝对详细)

Matrix Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 20599   Accept...
  • acm_BaiHuzi
  • acm_BaiHuzi
  • 2015年07月09日 16:49
  • 2895

poj2155 Matrix(经典二维树状数组)

吐槽:这题先说[x1,y1]和[x2,y2]是左上角和右下角的两个点,又说x1 http://poj.org/problem?id=2155 题意:输入n*n矩阵,有两个操作,C代表翻...
  • Flynn_curry
  • Flynn_curry
  • 2017年03月04日 13:37
  • 331

POJ 2155 Matrix (二维树状数组,区间更新,点查找)

题目链接:POJ 2155 Matrix 楼教主出的题。 【题目大意】 给你你 N x N的矩形区域, 开始时每个点的值都为0 有两种操作 C x1 y1 x2 y2 将区域 x1 到 x2 y1...
  • chaiwenjun000
  • chaiwenjun000
  • 2015年08月26日 15:50
  • 715

poj 2155 Matrix(树状数组)

Matrix Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 2...
  • zhangxiaoxiang123
  • zhangxiaoxiang123
  • 2015年09月17日 15:34
  • 133

POJ - 2155 Matrix 树状数组

Given an N*N matrix A, whose elements are either 0 or 1. A[i, j] means the number in the i-th row an...
  • YCQ_Lancet
  • YCQ_Lancet
  • 2017年04月08日 08:49
  • 119

poj - 2155 - Matrix(树状数组)

题意:对于一个N*N的矩阵(2 对矩阵(x1, y1, x2, y)的所有元素求反(0——>1, 1——>0),二:Q x y——>问元素(x, y)的值。 题目链接:http://poj.org/p...
  • SCNU_Jiechao
  • SCNU_Jiechao
  • 2014年01月25日 12:52
  • 867

[树状数组] poj 2155 Matrix

二维的区间更新单点查询
  • gdymind
  • gdymind
  • 2016年07月27日 10:39
  • 175
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:POJ 2155 Matrix 树状数组
举报原因:
原因补充:

(最多只允许输入30个字)