POJ 2155 Matrix 【二维线段树模板题】

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

只不过是结构体当中又套了一个而已,模板题不解释

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

using namespace std;
const int MAXN = 1010;
struct Nodey
{
    int l,r;
    int val;
};
int n;
int locx[MAXN],locy[MAXN];
struct Nodex
{
    int l,r;
    Nodey sty[MAXN*3];
    void build(int i,int _l,int _r)
    {
        sty[i].l = _l;
        sty[i].r = _r;
        sty[i].val = 0;
        if(_l == _r)
        {
            locy[_l] = i;
            return;
        }
        int mid = (_l + _r)>>1;
        build(i<<1,_l,mid);
        build((i<<1)|1,mid+1,_r);
    }
    void add(int i,int _l,int _r,int val)
    {
        if(sty[i].l == _l && sty[i].r == _r)
        {
            sty[i].val += val;
            return;
        }
        int mid = (sty[i].l + sty[i].r)>>1;
        if(_r <= mid)add(i<<1,_l,_r,val);
        else if(_l > mid)add((i<<1)|1,_l,_r,val);
        else
        {
            add(i<<1,_l,mid,val);
            add((i<<1)|1,mid+1,_r,val);
        }
    }
}stx[MAXN*3];
void build(int i,int l,int r)
{
    stx[i].l = l;
    stx[i].r = r;
    stx[i].build(1,1,n);
    if(l == r)
    {
        locx[l] = i;
        return;
    }
    int mid = (l+r)>>1;
    build(i<<1,l,mid);
    build((i<<1)|1,mid+1,r);
}
void add(int i,int x1,int x2,int y1,int y2,int val)
{
    if(stx[i].l == x1 && stx[i].r == x2)
    {
        stx[i].add(1,y1,y2,val);
        return;
    }
    int mid = (stx[i].l + stx[i].r)/2;
    if(x2 <= mid)add(i<<1,x1,x2,y1,y2,val);
    else if(x1 > mid)add((i<<1)|1,x1,x2,y1,y2,val);
    else
    {
        add(i<<1,x1,mid,y1,y2,val);
        add((i<<1)|1,mid+1,x2,y1,y2,val);
    }
}
int sum(int x,int y)
{
    int ret = 0;
    for(int i = locx[x];i;i >>= 1)
        for(int j = locy[y];j;j >>= 1)
            ret += stx[i].sty[j].val;
    return ret;
}

int main()
{
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int q;
        scanf("%d%d",&n,&q);
        build(1,1,n);
        char op[10];
        int x1,x2,y1,y2;
        while(q--)
        {
            scanf("%s",op);
            if(op[0] == 'C')
            {
                scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
                add(1,x1,x2,y1,y2,1);
            }
            else
            {
                scanf("%d%d",&x1,&y1);
                if(sum(x1,y1)%2 == 0)printf("0\n");
                else printf("1\n");
            }
        }
        if(T)printf("\n");
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值