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 ...
随机推荐
- 【Luogu】P1586四方定理(DP)
题目链接 此题使用DP.设f[i][j]表示数i用j个数表示,则对于所有的k<=sqrt(i),有 f[i][j]=∑f[i-k*k][j-1] 但是这样会有重复情况.所以先枚举k,再枚举i和j ...
- 【bzoj2238】Mst(树链剖分+线段树)
2238: Mst Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 465 Solved: 131[Submit][Status][Discuss] ...
- ReSharper7.1.25.234 注册机
经常用vs做开发的人都知道,ReSharper是vistual studio必备插件之一.他的智能提示,智能感知,.net底层方法查看,测试等都非常方便,给程序员带来了巨大的效率. 但众所周知ReSh ...
- Python入门--10--序列
一.与列表.元祖的相同与不同 1.都可以通索引得到元素 2.默认索引从0开始 3.可以通过分片得到一个范围内的元素集合 4.有很多共同的操作符 二. 1.list()这个函数用法 a="we ...
- docker-清理none镜像等操作
有时候由于调试代码产生很多的none的image,挨个清理会有些麻烦,从网上找到的命令 // 停止所有容器 docker ps -a | grep "Exited" | awk ' ...
- rman备份OBSOLETE和EXPIRED参数来历及区别
http://blog.itpub.net/30496894/viewspace-2096221/
- 洛谷—— P1051 谁拿了最多奖学金
https://www.luogu.org/problem/show?pid=1051 题目描述 某校的惯例是在每学期的期末考试之后发放奖学金.发放的奖学金共有五种,获取的条件各自不同: 1) 院士奖 ...
- JDK动态代理理解精髓
1.Java动态代理的关键是:Proxy类要和InvocationHandler的接口实现类,要用同一个目标target对象class,所以精髓是InvocationHandler和Proxy是一 ...
- nginx配置初步
nginx配置初步 1,切换至nginx目录,找到配置文件目录 cd /etc/nginx/conf.d 2,拷贝一份conf文件 sudo cp default.conf head.conf 3,进 ...
- cocos2d-x wp8 中文显示问题
cocos2d-x项目在wp8下中文显示不了.有两个原因: 1. 本身字符串的utf8编码, 有问题. 2. 显示中文所须要的字体,缺失. 要解决第二个问题非常easy,在fonts下加入一个中文字体 ...