http://poj.org/problem?id=2155

Matrix
Time Limit: 3000MS   Memory Limit: 65536K
Total Submissions: 18143   Accepted: 6813

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

谨以此题来祭我的第一道二维线段树!

没有30道线段树的基础不要碰二维线段树。

题意:

给出一个N×N的零矩阵。有两种操作:C x1 y1 x2 y2 是将(x1,y1) (x2,y2)相应范围内的矩阵中的0/1互换,Q x y是查询(x,y)位置元素的值。

分析:

0/1互换即异或操作,朴素的算法时间复杂度显然不够。假设是一维的坐标轴显然能够用线段树解,但这是一个二维的。那么就要用到二维线段树了。

以前的我天真地觉得二维线段树就是把一个矩形直接分成4份:左上、右上、左下、右下,后来遇到一个三维的题目我还YY出了把立方体分成8份来解(当然没过啦,并且标程也不是用线段树的)。

实际上,二维线段树是先将X坐标二分,然后再将Y轴二分。

第二维维护的也是一棵线段树,没错。二维线段树就是线段树套线段树!二分。再二分!

本题每次更新的时候先操作X轴,操作到相应区间时再对Y轴进行操作,从二维到一维。达到降维的效果。

查询时每次查到在所在的X区间内时都要对Y轴进行查询。

假设对线段树理解较深。相信对此不难理解。

详情请见代码(个人习惯维护左闭右开的区间,下标从0開始,所以有些调整):

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<algorithm>
#include<ctime>
#include<cctype>
#include<cmath>
#include<string>
#include<cstring>
#include<stack>
#include<queue>
#include<list>
#include<vector>
#include<map>
#include<set>
#define sqr(x) ((x)*(x))
#define LL long long
#define itn int
#define INF 0x3f3f3f3f
#define PI 3.1415926535897932384626
#define eps 1e-10
#define maxm
#define maxn 1007 using namespace std; int XOR[maxn<<2][maxn<<2];
int n,m; //update_1d() 更新一维
//[a,b)表示当前在一维操作的区间(Y方向)。k为节点标号,[l,r)表示节点相应维护的区间(Y方向),k_2d表示二维相应的节点标号
void update_1d(int a,int b,int k,int l,int r,int k_2d)
{
if (b<=l || r<=a) return ;
if (a<=l && r<=b)
{
XOR[k_2d][k]^=1;
}
else
{
update_1d(a,b,k*2+1,l,l+r>>1,k_2d);
update_1d(a,b,k*2+2,l+r>>1,r,k_2d);
}
} //update_2d() 更新二维
//[a,b)表示当前在二维操作的区间(X方向)。[y1,y2)表示将要在一维操作的区间(Y方向),k为节点标号,[l,r)表示节点相应维护的区间(X方向)
void update_2d(int a,int b,int y1,int y2,int k,int l,int r)
{
if (b<=l || r<=a) return ;
if (a<=l && r<=b)
{
update_1d(y1,y2,0,0,n,k);
}
else
{
update_2d(a,b,y1,y2,k*2+1,l,l+r>>1);
update_2d(a,b,y1,y2,k*2+2,l+r>>1,r);
}
} //query_1d() 查询一维
//p表示当前在一维查询的位置(Y方向),k为节点标号,[l,r)表示节点相应维护的区间(Y方向),k_2d表示二维相应的节点标号
int query_1d(int p,int k,int l,int r,int k_2d)
{
if (r-l==1) return XOR[k_2d][k]; int m=l+r>>1; if (p<m)
return XOR[k_2d][k]^query_1d(p,k*2+1,l,m,k_2d);
else
return XOR[k_2d][k]^query_1d(p,k*2+2,m,r,k_2d);
} //query_2d() 查询二维
//px表示当前在二维查询的位置(X方向),py表示将要在一维查询的位置(Y方向),k为节点标号。[l,r)表示节点相应维护的区间(X方向)
int query_2d(int px,int py,int k,int l,int r)
{
int res=query_1d(py,0,0,n,k);// attention please! if (r-l==1) return res; int m=l+r>>1; if (px<m)
return res^query_2d(px,py,k*2+1,l,m);
else
return res^query_2d(px,py,k*2+2,m,r);
} int main()
{
#ifndef ONLINE_JUDGE
freopen("/home/fcbruce/文档/code/t","r",stdin);
#endif // ONLINE_JUDGE int T_T;
scanf("%d",&T_T); while (T_T--)
{ scanf("%d %d",&n,&m);
memset(XOR,0,sizeof XOR); for (int i=0;i<m;i++)
{
char op;
int x1,x2,y1,y2; getchar();
op=getchar(); if (op=='C')
{
scanf("%d %d %d %d",&x1,&y1,&x2,&y2);
x1--;y1--;
update_2d(x1,x2,y1,y2,0,0,n);
}
else
{
scanf("%d %d",&x1,&y1);
x1--;y1--;
printf("%d\n",query_2d(x1,y1,0,0,n));
}
} if (T_T) putchar('\n'); //由于这个PE一发
} return 0;
}

版权声明:本文博主原创文章,博客,未经同意不得转载。

POJ 2155 Matrix (D区段树)的更多相关文章

  1. POJ 2155 Matrix(二维树状数组,绝对具体)

    Matrix Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 20599   Accepted: 7673 Descripti ...

  2. poj 2155 Matrix (二维树状数组)

    题意:给你一个矩阵开始全是0,然后给你两种指令,第一种:C x1,y1,x2,y2 就是将左上角为x1,y1,右下角为x2,y2,的这个矩阵内的数字全部翻转,0变1,1变0 第二种:Q x1 y1,输 ...

  3. POJ poj 2155 Matrix

    题目链接[http://poj.org/problem?id=2155] /* poj 2155 Matrix 题意:矩阵加减,单点求和 二维线段树,矩阵加减,单点求和. */ using names ...

  4. POJ 2155 Matrix【二维树状数组+YY(区间计数)】

    题目链接:http://poj.org/problem?id=2155 Matrix Time Limit: 3000MS   Memory Limit: 65536K Total Submissio ...

  5. poj 2155:Matrix(二维线段树,矩阵取反,好题)

    Matrix Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 17880   Accepted: 6709 Descripti ...

  6. POJ 2155 Matrix (二维线段树)

    Matrix Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 17226   Accepted: 6461 Descripti ...

  7. poj 2155 Matrix (树状数组)

    Matrix Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 16797   Accepted: 6312 Descripti ...

  8. POJ 2155 Matrix(树状数组+容斥原理)

    [题目链接] http://poj.org/problem?id=2155 [题目大意] 要求维护两个操作,矩阵翻转和单点查询 [题解] 树状数组可以处理前缀和问题,前缀之间进行容斥即可得到答案. [ ...

  9. 【树状数组】POJ 2155 Matrix

    附一篇经典翻译,学习 树状数组  http://www.hawstein.com/posts/binary-indexed-trees.html /** * @author johnsondu * @ ...

随机推荐

  1. linuxserver启动过程

    随着Linux的应用日益广泛.特别是在网络应用方面,有大量的网络server使用Linux操作系统.因为Linux的桌面应用和Windows相比另一 定的差距.所以在企业应用中往往是Linux和Win ...

  2. Visual Studio跨平台开发实战(4) - Xamarin Android基本控制项介绍

    原文 Visual Studio跨平台开发实战(4) - Xamarin Android基本控制项介绍 前言 不同于iOS,Xamarin 在Visual Studio中针对Android,可以直接设 ...

  3. IOS开发-通知与消息机制

    在多数移动应用中不论什么时候都仅仅能有一个应用程序处于活跃状态.假设其它应用此刻发生了一些用户感兴趣的那么通过通知机制就能够告诉用户此时发生的事情. iOS中通知机制又叫消息机制,其包含两类:一类是本 ...

  4. 构造Nexus,仓库部署成员Nexus仓

    在一个,我们描述了如何配置安装nexus制,本节,我们来介绍nexus采用 1.登录 在红色的部分点击登陆.输入username与password admin/admin123. 这里能够配置nexu ...

  5. 第三章 AOP 基于Schema的AOP

    基于Schema定义的切面和前现两种方式定义的切面,内容上都差不多,只是表现形式不一样而已. 3.7.1一般增强的使用 a.目标类 public class Target { public void ...

  6. 大爱jQuery,10美女模特有用jQuery/CSS3插入(集成点免费下载)

    整合下载地址:http://download.csdn.net/detail/yangwei19680827/7343001 jQuery真的是一款非常犀利的Javascript框架,利用jQuery ...

  7. 【迷你微信】基于MINA、Hibernate、Spring、Protobuf的即时聊天系统:3.技术简介之MinaFilter——LoggingFilter (转)

    欢迎阅读我的开源项目<迷你微信>服务器与<迷你微信>客户端 LoggingFilter 接下来,使我们对Filter介绍的最后一个——LoggingFilter. 与Proto ...

  8. 索尼 LT26I刷机包 X.I.D 增加官方风格 GF A3.9.4 各方面完美

    ROM介 FX_GF_A系列是具有官方风格的.稳定的.流畅的.省电的.新功能体验的.最悦耳音效体验的ROM. FX_GF_A更新日志 ☆ GF_3.9.4 更新信息 ☆ 更新播放器 ☆ 更新adsp数 ...

  9. 边记边学PHP-(十五)MySQL数据库基础操作2

    四.使用可视化工具创建数据库 尽管使用命令行感觉更像我们程序猿,可是我还是比較喜欢使用workbench来创建数据库. 首先打开workbench , 一个比較友好的界面就打开了,哈哈.我还是比較喜欢 ...

  10. php zip文件内容比較类

    php zip 文件比較类,比較两个zip文件的内容,返回新增,删除,及同样的文件列表.临时仅仅支持单层. 需求:上传一个zip文件,zip内有非常多图片文件.须要对图片文件进行一系列非常耗时的处理. ...