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

原创 2015年07月09日 16:49:49
Matrix
Time Limit: 3000MS   Memory Limit: 65536K
Total Submissions: 20599   Accepted: 7673

Description

Given an N*N matrix A, whose elements are either 0 or 1. A[i, j] means the number in the i-th row and j-th column. Initially we have A[i, j] = 0 (1 <= i, j <= N). 

We can change the matrix in the following way. Given a rectangle whose upper-left corner is (x1, y1) and lower-right corner is (x2, y2), we change all the elements in the rectangle by using "not" operation (if it is a '0' then change it into '1' otherwise change it into '0'). To maintain the information of the matrix, you are asked to write a program to receive and execute two kinds of instructions. 

1. C x1 y1 x2 y2 (1 <= x1 <= x2 <= n, 1 <= y1 <= y2 <= n) changes the matrix by using the rectangle whose upper-left corner is (x1, y1) and lower-right corner is (x2, y2). 
2. Q x y (1 <= x, y <= n) querys A[x, y]. 

Input

The first line of the input is an integer X (X <= 10) representing the number of test cases. The following X blocks each represents a test case. 

The first line of each block contains two numbers N and T (2 <= N <= 1000, 1 <= T <= 50000) representing the size of the matrix and the number of the instructions. The following T lines each represents an instruction having the format "Q x y" or "C x1 y1 x2 y2", which has been described above. 

Output

For each querying output one line, which has an integer representing A[x, y]. 

There is a blank line between every two continuous test cases. 

Sample Input

1
2 10
C 2 1 2 2
Q 2 2
C 2 1 2 1
Q 1 1
C 1 1 2 1
C 1 2 1 2
C 1 1 2 2
Q 1 1
C 1 1 2 1
Q 2 1

Sample Output

1
0
0
1

Source

POJ Monthly,Lou Tiancheng

题意:给出矩阵左上角和右下角坐标,矩阵里的元素 1变0 ,0 变1,然后给出询问,问某个点是多少。

题解:纠结了好久,看了这篇博客后秒懂http://blog.sina.com.cn/s/blog_626489680100k75p.html

          先举个一维的例子:你要使区间[x,y]全部加上一个值v,结合树状数组的功能,可以类似扫气球那样,在x处加v, y+1处减1

          这样如果你要求x处的值,就转换成求[1,x]的和了,例如 :一个n=6的数组,一开始为0  0  0   0  0  0

         在[2,4]加上2后变成   0   2   0   0   -2    0  这样前缀和 sum[1]=0;sum[2]=2;sum[3]=2;sum[4]=2;sum[5]=0;sum[6]=0;

        依次代表了每个数的值。

       二维的也一样,因为二维树状数组的getsum(int x,int y)函数是求矩阵(1,1)~(x,y)的值得和,也就类似于前缀和,原理和一维的一样

       只不过线操作改成了平面操作,自己可以画个图感受下。

      

                即:

               add(x,y,1);
                add(x,y1+1,-1);
                add(x1+1,y,-1);
                add(x1+1,y1+1,1);

               然后查询单点就是求和了。

     

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#define N 1040
#define ll long long

using namespace std;

int n;

int bit[N][N];

int sum(int i,int j) {
    int s=0;
    while(i>0) {
        int jj=j;
        while(jj>0) {
            s+=bit[i][jj];
            jj-=jj&-jj;
        }
        i-=i&-i;
    }
    return s;
}

void add(int i,int j,int x) {
    while(i<=n) {
        int jj=j;
        while(jj<=n) {
            bit[i][jj]+=x;
            jj+=jj&-jj;
        }
        i+=i&-i;
    }
}

int main() {
    freopen("test.in","r",stdin);
    int t;
    cin>>t;
    while(t--) {
        int q;
        scanf("%d%d ",&n,&q);
        memset(bit,0,sizeof bit);
        char c;
        int x,y,x1,y1;
        while(q--) {
            scanf("%c",&c);
            if(c=='C') {
                scanf("%d%d%d%d",&x,&y,&x1,&y1);
                add(x,y,1);
                add(x,y1+1,-1);
                add(x1+1,y,-1);
                add(x1+1,y1+1,1);//重叠的部分加上
            } else {
                scanf("%d%d",&x,&y);
                printf("%d\n",sum(x,y)%2);
            }
            getchar();
        }
        if(t)printf("\n");
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

Leetcode解题笔记(Array)

源码见github https://github.com/Kelvinmao/Leetcode/tree/master/Array 2016-08-08更新154.Find Minimum in Ro...
  • kelvinmao
  • kelvinmao
  • 2016年07月23日 22:38
  • 1565

给定一数组a[N],我们希望构造数组b [N],其中b[j]=a[0]*a[1]…a[N-1] / a[j]

地址:http://blog.csdn.net/morewindows/article/details/8742666转载请标明出处,谢谢。 欢迎关注微博:http://weibo.com/Mo...
  • zxasqwedc
  • zxasqwedc
  • 2014年11月17日 20:17
  • 1726

POJ2155 Matrix 二维树状数组 修改区域,查询节点

Problem Address:http://poj.org/problem?id=2155 【前言】 参考资料:http://blog.csdn.net/Human_CK/archive/2011/...
  • Human_CK
  • Human_CK
  • 2011年06月14日 09:45
  • 609

poj2155 Matrix 二维树状数组

题意:一个01矩阵,进行两种操作,一种是对一个子矩阵的数字进行反转,0变1,1变0。还有一种是查询一个数字。 这里涉及频繁的区间修改和查询,可以考虑使用树状数组。 因为是一个矩阵,所以要拓展到...
  • yhn19951008
  • yhn19951008
  • 2017年06月26日 14:37
  • 83

POJ2155_Matrix_二维树状数组

Matrix Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 27601   Accept...
  • yuege38
  • yuege38
  • 2017年05月23日 16:32
  • 71

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
  • 700

POJ 2155 Matrix(二维树状数组)

题目链接: http://poj.org/problem?id=2155 题目大意: 给一个n*n的矩阵,有k个询问。询问分更新和询问操作。 更新操作是对某个小的矩阵进行变换,里面的数(0变1,1变...
  • aaaaacmer
  • aaaaacmer
  • 2016年03月04日 21:48
  • 245

poj 2155 Matrix(二维树状数组,好题)中等难度题目,更新区域,查询单点

1、http://poj.org/problem?id=2155 2、题目大意: 有一个n*n的矩阵,初始值时0,现在对该矩阵做两种操作,C x1 y1 x2 y2,是将这一区域的值是0的换成1,是1...
  • sdjzping
  • sdjzping
  • 2014年03月04日 10:38
  • 782

poj 2155 Matrix(二维树状数组)

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

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
  • 2605
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:POJ 2155 Matrix(二维树状数组,绝对详细)
举报原因:
原因补充:

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