POJ2155 Matrix 二维线段树
关键词:线段树
二维线段树维护一个 维护一个X线段的线段树,每个X节点维护一个 维护一个Y线段的线段树。
注意,以下代码没有PushDownX。因为如果要这么做,PushDownX时,由于当前X节点的子节点可能存在标记,而标记不能叠加,导致每次PushDownX时都要把子节点PushDownX一次。每次PushDownX都要对子节点UpdateY,代价太高。这种情况下原则是:只有查询操作<<更新操作时才PushDownX。
#include <cstdio>
#include <cstring>
#include <cassert>
#include <vector>
using namespace std; const int MAX_X = , MAX_Y = ; struct RangeTree2d
{
private:
bool Rev[MAX_X * ][MAX_Y * ];
int YlMin, YrMax, XlMin, XrMax; void PushDownY(int xCur, int yCur)
{
if (Rev[xCur][yCur])
{
Rev[xCur][yCur * ] ^= ;
Rev[xCur][yCur * + ] ^= ;
Rev[xCur][yCur] = false;
}
} void UpdateY(int xCur, int yCur, int sl, int sr, int al, int ar)
{
assert(sl <= sr&&al <= ar&&al <= sr&&ar >= sl);
if (al <= sl&&sr <= ar)
{
Rev[xCur][yCur] ^= ;
return;
}
int mid = (sr - sl) / + sl;
if (al <= mid)
UpdateY(xCur, yCur * , sl, mid, al, ar);
if (ar > mid)
UpdateY(xCur, yCur * + , mid + , sr, al, ar);
} void UpdateY(int xCur, int l, int r)
{
UpdateY(xCur, , YlMin, YrMax, l, r);
} bool QueryY(int xCur, int yCur, int l, int r, int y)
{
if (l == r)
return Rev[xCur][yCur];
PushDownY(xCur, yCur);
int mid = (l + r) / ;
if (y <= mid)
return QueryY(xCur, yCur * , l, mid, y);
else
return QueryY(xCur, yCur * + , mid + , r, y);
} bool QueryY(int xCur, int y)
{
return QueryY(xCur, , YlMin, YrMax, y);
} void UpdateX(int xCur, int sl, int sr, int al, int ar, int yl, int yr)
{
//printf("C x:sl %d sr %d al %d ar %d\n", sl, sr, al, ar);
assert(sl <= sr&&al <= ar&&al <= sr&&ar >= sl);
if (al <= sl&&sr <= ar)
{
UpdateY(xCur, yl, yr);
return;
}
int mid = (sr - sl) / + sl;
if (al <= mid)
UpdateX(xCur * , sl, mid, al, ar, yl, yr);
if (ar > mid)
UpdateX(xCur * + , mid + , sr, al, ar, yl, yr);
} void QueryX(int xCur, int l, int r, int x, int y, bool &ans)
{
ans ^= QueryY(xCur, y);
if (l == r)
return;
int mid = (l + r) / ;
if (x <= mid)
QueryX(xCur * , l, mid, x, y, ans);
else
QueryX(xCur * + , mid + , r, x, y, ans);
} public:
void Init(int xlMin, int xrMax, int ylMin, int yrMax)
{
XlMin = xlMin;
XrMax = xrMax;
YlMin = ylMin;
YrMax = yrMax;
memset(Rev, false, sizeof(Rev));
} void Update(int xl, int xr, int yl, int yr)
{
UpdateX(, XlMin, XrMax, xl, xr, yl, yr);
} int Query(int x, int y)
{
bool ans = false;
QueryX(, XlMin, XrMax, x, y, ans);
return ans;
}
}g; int main()
{
#ifdef _DEBUG
freopen("c:\\noi\\source\\input.txt", "r", stdin);
#endif
int totCase;
scanf("%d", &totCase);
while (totCase--)
{
int mSize, qCnt;
scanf("%d%d", &mSize, &qCnt);
g.Init(, mSize, , mSize);
while (qCnt--)
{
char op;
int x1, x2, y1, y2;
scanf("\n%c", &op);
switch (op)
{
case 'C':
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
g.Update(x1, x2, y1, y2);
break;
case 'Q':
scanf("%d%d", &x1, &y1);
printf("%d\n", g.Query(x1, y1));
break;
default:
assert();
}
}
printf("\n");
}
return ;
}
反思:
1.不用动态开点,因为内存够。动态申请内存费时间。
2.不要将问题扩大化为求区域面积,提高了编程复杂度。
POJ2155 Matrix 二维线段树的更多相关文章
- POJ2155 Matrix二维线段树经典题
题目链接 二维树状数组 #include<iostream> #include<math.h> #include<algorithm> #include<st ...
- POJ 2155 Matrix (二维线段树入门,成段更新,单点查询 / 二维树状数组,区间更新,单点查询)
题意: 有一个n*n的矩阵,初始化全部为0.有2中操作: 1.给一个子矩阵,将这个子矩阵里面所有的0变成1,1变成0:2.询问某点的值 方法一:二维线段树 参考链接: http://blog.csdn ...
- poj 2155 matrix 二维线段树 线段树套线段树
题意 一个$n*n$矩阵,初始全为0,每次翻转一个子矩阵,然后单点查找 题解 任意一种能维护二维平面的数据结构都可以 我这里写的是二维线段树,因为四分树的写法复杂度可能会退化,因此考虑用树套树实现二维 ...
- poj 2155 matrix 二维线段树
题目链接 区间翻转, 单点查询, 查询操作我真是不太明白...... #include <iostream> #include <vector> #include <cs ...
- POJ2155 Matrix 【二维线段树】
题目链接 POJ2155 题解 二维线段树水题,蒟蒻本想拿来养生一下 数据结构真的是有毒啊,, TM这题卡常 动态开点线段树会TLE[也不知道为什么] 直接开个二维数组反倒能过 #include< ...
- 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: 17880 Accepted: 6709 Descripti ...
- [poj2155]Matrix(二维树状数组)
Matrix Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 25004 Accepted: 9261 Descripti ...
- ZOJ 1859 Matrix Searching(二维线段树)
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1859 Matrix Searching Time Limit: 10 Seco ...
随机推荐
- cf21D Traveling Graph
You are given undirected weighted graph. Find the length of the shortest cycle which starts from the ...
- iOS 取应用版本
// 应用网址 返回字典中有多种数据 NSString *urlString2 = [NSString stringWithFormat: @"%@", @"http: ...
- ajax 分页(jquery分页插件pagination) 小例1
<link rel="stylesheet" href="/plugins/jQuery/page/pagination.css"/> <sc ...
- ubuntu下用webbench做网站压力测试
安装依赖 exuberant-ctags sudo apt-get install exuberant-ctags 下载源码并安装 wget http://blog.s135.com/soft/lin ...
- HTML 中 SELECT 选项分组
<select name="viewType"> <option value selected>选择排序/显示方式</option> <o ...
- git(三):第一次github了解使用
第一次使用github,看了一下使用说明,创建第一个repository,以后还要多学习. 一.Github创建一个新仓库 ······Creat a new repository 创建一个新仓库,点 ...
- [Bzoj3677][Apio2014]连珠线(树形dp)
3677: [Apio2014]连珠线 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 434 Solved: 270[Submit][Status] ...
- Chrome 浏览器安装Vue插件方法 (十分详细)
博主最近在研究Vue,无奈新手想安装Chrome的Vue插件,整理下安装流程: 1.首先去github下载vue.zip文件插件(还有npm安装方法这里就不介绍了自行百度)下载地址:https://g ...
- [转] sql 删除表数据的drop、truncate和delete用法
删除表数据的关键字,大家记得最多的可能就是delete.然而,我们做数据库开发,读取数据库数据.对另外的drop.truncate用得就比较少了. 1 drop 出没场合:drop table ta ...
- AtoS查看iOS Crash log中的16进制代码日志
注意:crash_log一定要和打包时的archive对应上: 方法1)在Orgnizer里找到某一个archive,即:/Users/handywang/Library/Developer/Xcod ...