POJ 2155 Matrix (D区段树)
http://poj.org/problem?id=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 Sample Output 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区段树)的更多相关文章
- POJ 2155 Matrix(二维树状数组,绝对具体)
Matrix Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 20599 Accepted: 7673 Descripti ...
- poj 2155 Matrix (二维树状数组)
题意:给你一个矩阵开始全是0,然后给你两种指令,第一种:C x1,y1,x2,y2 就是将左上角为x1,y1,右下角为x2,y2,的这个矩阵内的数字全部翻转,0变1,1变0 第二种:Q x1 y1,输 ...
- POJ poj 2155 Matrix
题目链接[http://poj.org/problem?id=2155] /* poj 2155 Matrix 题意:矩阵加减,单点求和 二维线段树,矩阵加减,单点求和. */ using names ...
- POJ 2155 Matrix【二维树状数组+YY(区间计数)】
题目链接:http://poj.org/problem?id=2155 Matrix Time Limit: 3000MS Memory Limit: 65536K Total Submissio ...
- poj 2155:Matrix(二维线段树,矩阵取反,好题)
Matrix Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 17880 Accepted: 6709 Descripti ...
- POJ 2155 Matrix (二维线段树)
Matrix Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 17226 Accepted: 6461 Descripti ...
- poj 2155 Matrix (树状数组)
Matrix Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 16797 Accepted: 6312 Descripti ...
- POJ 2155 Matrix(树状数组+容斥原理)
[题目链接] http://poj.org/problem?id=2155 [题目大意] 要求维护两个操作,矩阵翻转和单点查询 [题解] 树状数组可以处理前缀和问题,前缀之间进行容斥即可得到答案. [ ...
- 【树状数组】POJ 2155 Matrix
附一篇经典翻译,学习 树状数组 http://www.hawstein.com/posts/binary-indexed-trees.html /** * @author johnsondu * @ ...
随机推荐
- 官方原版Windows XP SP3(VOL)中文简体版ISO下载
今天,向各位朋友推荐今年五月,由MSDN官方集成的XP With SP3专业VOL版. 文 件:Windows XP Professional with Service Pack 3 (x86) ...
- Mega的简单使用
Table of Contents 1 Mega画树的简单应用 2 fas格式文件的准备 3 用生成的.meg画树 4 生出树的处理 4.1 修改内容,添加标注 4.2 导出 4.3 后面随着学习的进 ...
- 索尼 LT26I刷机包 X.I.D 增加官方风格 GF A3.9.4 各方面完美
ROM介 FX_GF_A系列是具有官方风格的.稳定的.流畅的.省电的.新功能体验的.最悦耳音效体验的ROM. FX_GF_A更新日志 ☆ GF_3.9.4 更新信息 ☆ 更新播放器 ☆ 更新adsp数 ...
- Firefox双击关闭标签
- enumerateObjectsUsingBlock、enumerateObjectsWithOptions、enumerateObjectsAtIndexes、makeObjectsPerfor使用
OC至 NSArray它提供了一个方便的遍历block,以下具体说明 第一.enumerateObjectsUsingBlock NSArray *array=@[@"aa",@& ...
- C++编程有趣的标题1 于1~9填写的运算结果的中间符号等于100
于1 2 3 4 5 6 7 8 9将九个数字"+"要么"-"符号使得结果100,编程的所有组合. 注意:数字顺序不能改变 <pre name=" ...
- redmine忘记username和password
环境: Ubuntu 13.10 bitnami-redmine-2.5.1-1-linux-x64-installer.run 用bitnami安装完redmine以后,有是否忘记了username ...
- 制作简易计算器处理过程Servlet
CalculationServlet.java: package com.you.servlet; import java.io.IOException; import java.io.PrintWr ...
- 每天努力一点之SQL
今天工作当中遇到一个问题:统计信息并导出EXcel 报表. 刚开始只做了统计信息: 如下图 请看最后一列的数据. 我当时想都从数据库里取出来,但是由于我能力有限没有做出来.先贴下后来写的SQL 语句. ...
- CAS实现SSO单点登录原理(转)
1. CAS 简介 1.1. What is CAS ? CAS ( Central Authentication Service ) 是 Yale 大学发起的一个企业级的.开源的项目,旨 ...