博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
POJ2155 Matrix 二维线段树
阅读量:4944 次
发布时间:2019-06-11

本文共 3776 字,大约阅读时间需要 12 分钟。

关键词:线段树

二维线段树维护一个 维护一个X线段的线段树,每个X节点维护一个 维护一个Y线段的线段树。

 

注意,以下代码没有PushDownX。因为如果要这么做,PushDownX时,由于当前X节点的子节点可能存在标记,而标记不能叠加,导致每次PushDownX时都要把子节点PushDownX一次。每次PushDownX都要对子节点UpdateY,代价太高。这种情况下原则是:只有查询操作<<更新操作时才PushDownX。

#include 
#include
#include
#include
using namespace std;const int MAX_X = 2000, MAX_Y = 2000;struct RangeTree2d{
private: bool Rev[MAX_X * 4][MAX_Y * 4]; int YlMin, YrMax, XlMin, XrMax; void PushDownY(int xCur, int yCur) { if (Rev[xCur][yCur]) { Rev[xCur][yCur * 2] ^= 1; Rev[xCur][yCur * 2 + 1] ^= 1; 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] ^= 1; return; } int mid = (sr - sl) / 2 + sl; if (al <= mid) UpdateY(xCur, yCur * 2, sl, mid, al, ar); if (ar > mid) UpdateY(xCur, yCur * 2 + 1, mid + 1, sr, al, ar); } void UpdateY(int xCur, int l, int r) { UpdateY(xCur, 1, 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) / 2; if (y <= mid) return QueryY(xCur, yCur * 2, l, mid, y); else return QueryY(xCur, yCur * 2 + 1, mid + 1, r, y); } bool QueryY(int xCur, int y) { return QueryY(xCur, 1, 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) / 2 + sl; if (al <= mid) UpdateX(xCur * 2, sl, mid, al, ar, yl, yr); if (ar > mid) UpdateX(xCur * 2 + 1, mid + 1, 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) / 2; if (x <= mid) QueryX(xCur * 2, l, mid, x, y, ans); else QueryX(xCur * 2 + 1, mid + 1, 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(1, XlMin, XrMax, xl, xr, yl, yr); } int Query(int x, int y) { bool ans = false; QueryX(1, 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(1, mSize, 1, 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(0); } } printf("\n"); } return 0;}

 

反思:

1.不用动态开点,因为内存够。动态申请内存费时间。

2.不要将问题扩大化为求区域面积,提高了编程复杂度。

转载于:https://www.cnblogs.com/headboy2002/p/8443731.html

你可能感兴趣的文章
发送带有正文以及附件的邮件
查看>>
video视频限时观看
查看>>
eclipse下载安装
查看>>
Jquery中ajax加载提示插件blickUI
查看>>
Tomcat 启动报错 did not find a matching property.
查看>>
Fast DFS分布式文件存储系统
查看>>
选择排序算法---直接选择排序和堆排序
查看>>
读文件
查看>>
The 'Microsoft.ACE.OLEDB.12.0' provider is not registered on the local machine.
查看>>
[C++]指针学习总结
查看>>
多线程之——共享数据
查看>>
errorlevel 续1
查看>>
堆 续8
查看>>
@RequestBody使用须知
查看>>
20172330 2017-2018-1 《Java程序设计》第五周学习总结
查看>>
Objective-C runtime 机制
查看>>
目标检测入门
查看>>
React js ReactDOM.render 语句后面不能加分号
查看>>
iOS开发常用第三方库
查看>>
堆排序法---题目
查看>>