POJ 2155 Matrix(树状数组)

Matrix

Time Limit: 3000MS   Memory Limit: 65536K
Total Submissions: 20138   Accepted: 7522

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

题意:poj1566的二维版,有一个矩阵,矩阵中的每个元素只能有0,1,表示,给定一个矩形的左上角和右下角,在这个矩形中的元素进行取反。当输入的字符为Q是,输出地址为x行y列的那个元素是0还是1.

#include <iostream>
#include<algorithm>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

using namespace std;

#define maxn 1005

int a[maxn][maxn];
int r,l;
int n;

inline int Lowbit(int x)
{
    return x & (-x);
}

int Sum(int x, int y)
{
    int temp, sum = 0;
    while (x)
    {
        temp = y;
        while (temp)
        {
            sum += a[x][temp];
            temp -= Lowbit(temp);
        }
        x -= Lowbit(x);
    }
    return sum;
}

void Update(int x, int y, int num)
{
    int temp;
    while (x <= n)
    {
        temp = y;
        while (temp <= n)
        {
            a[x][temp] += num;
            temp += Lowbit(temp);
        }
        x += Lowbit(x);
    }
}

int main()
{
    int x, m;
    scanf("%d", &x);
    while (x--)
    {
        memset(a, 0, sizeof(a));
        scanf("%d%d", &n, &m);
        getchar();
        l = n;
        r = n;
        for (int i = 0; i < m; i++)
        {
            char ch;
            int x1, x2, y2, y1;
            scanf("%c", &ch);
            if (ch == 'C')
            {
                scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
                x2++;
                y2++;
                Update(x1, y1, 1);
                Update(x1, y2, -1);
                Update(x2, y1, -1);
                Update(x2, y2, 1);
            }
            else
            {
                scanf("%d%d", &x1, &y1);
                printf("%d\n", (Sum(x1, y1)%2));
            }
            getchar();
        }
        printf("\n");
    }
    return 0;
}
时间: 2024-08-24 02:17:52

POJ 2155 Matrix(树状数组)的相关文章

POJ 2155 Matrix (树状数组 &amp;&amp; 区间计数)

题意 : 给出一个N*N的矩阵, 矩阵只有可能包含0或1, 一开始则全部是0.对于矩阵可以进行两种操作, 第一种是输入 C x1 y1 x2 y2 表示, 对以(x1, y1)为左上角, 以(x2, y2)为右下角构成的矩形区域内的数全部进行取反操作, 即0变1.1变0.第二种是Q X Y, 表示查询现在这个矩阵的(X, Y)点到底是0还是1.总共有T次操作, 对于C操作进行相应的修改, 对于Q操作要对应输出! 分析 : 据说是楼教主出的题, 自己确实想不出什么高效的办法, 参考网上的题解, 才

poj 2155 Matrix(树状数组的应用)

http://poj.org/problem?id=2155 对于一个n*n(n <= 1000)的01矩阵,初始全为0,有两种操作. C x1 y1 x2 y2 ,分别代表矩阵的左上角和右下角,将这个矩阵中的01互换,原为0的变为1,原为1的变为0. Q x y询问A[x,y]现在是几. 因为只有01的互换,且原始为0,那么只需计算[x,y]处被换了几次就能确定现在这个格子是几.重点就是怎样快速计算[x,y]格子被换了几次.操作方法是将[x1,y1][x1,y2+1][x2+1,y1][x2+

POJ 2309 BST 树状数组基本操作

Description Consider an infinite full binary search tree (see the figure below), the numbers in the nodes are 1, 2, 3, .... In a subtree whose root node is X, we can get the minimum number in this subtree by repeating going down the left node until t

Poj 2299 Ultra-QuickSort 树状数组 解法

本题的树状数组稍微有点特点,就是需要所谓的离散化一下,开始听这个名称好像很神秘的,不过其实很简单. 就是把一个数组arr的值,其中的值是不连续的,变成一组连续的值,因为这样他们的顺序是不变的,所以,不影响结果. 例如:9 1 0 5 4 ->变为:5 2 1 4 3看出他们的相对位置不变的. 9和5为最大值在第一个位置,1和2为第二大的值在第二个位置,0和1在第一个位置等,看出对应顺序了吗? 对,就是这么简单的方法, 就叫做离散化. 如果你对counting sort熟悉的话,那么这样的思想理解

POJ 2481 Cows(树状数组)

Description Farmer John's cows have discovered that the clover growing along the ridge of the hill (which we can think of as a one-dimensional number line) in his field is particularly good. Farmer John has N cows (we number the cows from 1 to N). Ea

POJ 2352 Stars(树状数组 or 线段树)

链接: http://poj.org/problem?id=2352 题目大意: 在坐标上有n个星星,如果某个星星坐标为(x, y), 它的左下位置为:(x0,y0),x0<=x 且y0<=y.如果左下位置有a个星星,就表示这个星星属于level x 按照y递增,如果y相同则x递增的顺序给出n个星星,求出所有level水平的数量. 思路: 由于输入的顺序,对于第i颗星星,它的等级是之前输入的星星中,横坐标x小于等于i星横坐标的那些星星的总数量(前面的y一定比后面的y小). 所以是查询+更新操作

poj 2481 Cows 树状数组解法,详细解析。

Cows Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 13445   Accepted: 4448 Description Farmer John's cows have discovered that the clover growing along the ridge of the hill (which we can think of as a one-dimensional number line) in hi

POJ 2481 Cows &amp;&amp; POJ 2352 Stars(树状数组妙用)

题目链接:POJ 2481 Cows POJ 2352 Stars 发现这两个题目都跟求逆序数有着异曲同工之妙,通过向树状数组中插入点的位置,赋值为1,或者++,然后通过求和来判断比当前 点 "小" 的有多少点. Cows需要自己排序, Stars题目已经给排好序. POJ 2352 Stars 题目大意为在二维坐标上给出一些星星的坐标,求某一个星星左方,下方,左下方的星星个数.题目已经把星星按照Y坐标从小到大,X从小到大排序.因此,在每次对一个星星进行统计时,之前出现过的星星,只要X

POJ 2299 Ultra-QuickSort(树状数组 + 离散)

链接:http://poj.org/problem?id=2299 题意:给出N个数组成的数列A(0 <= A[i] <= 999,999,999),求该数列逆序对的数量. 分析:题目所谓的排序过程其实就是一个冒泡排序的过程.在这里,我们需要知道,冒泡排序所需交换的次数等于该序列逆序对的数量(证明略).这是这道题的一个切入点. 树状数组可以很方便地求出数列的前缀和,对于一个数x,我们使树状数组上第x个元素的值赋为1,这时调用Sum(x)就可以得到一个从第1项到第x项的前缀和.这意味着我们可以通

POJ 2352 【树状数组】

题意: 给了很多星星的坐标,星星的特征值是不比他自己本身高而且不在它右边的星星数. 给定的输入数据是按照y升序排序的,y相同的情况下按照x排列,x和y都是介于0和32000之间的整数.每个坐标最多有一个星星. 思路: 这题给的输入数据很祥和,间接提示思路了. 用x作为树状数组的区间,然后按照输入的顺序不断查找在包括自己的位置以及左边的星星数. 细节是x可能是0,这是树状数组不能接受的,需要对输入的x数据进行加一操作. 从这题可以看出树状数组最直白的作用就是求从1开始到某个点的某个区间的数量. #