博客
关于我
poj2528 Mayor‘s posters(线段树+离散化)
阅读量:611 次
发布时间:2019-03-12

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

题目链接:

题目大意:
多组输入,每组给出两个整数n和n表示一个区间,依次向一面墙上染不同的色,问染色后墙上能看见几种颜色。

题目分析:

这是一个经典的线段树染色问题。由于区间的值域较大,为了减少内存占用和提高效率,通常可以通过离散化(Discretization)将区间映射到较小的范围内。具体来说,可以将所有区间的左右端点收集起来,排序并去重,得到一个唯一的离散值域。这样可以将原来的连续区间映射到一个有限的离散点上,从而减少线段树的空间复杂度。

在实际实现中,可以使用线段树来维护区间信息,每个节点记录区间的值以及是否被覆盖。通过线段树的分治特性,可以高效地进行区间更新和查询操作。最后,可以通过查询线段树中的被覆盖的最小值和最大值,确定最终的颜色覆盖情况。

具体细节见代码:

#include 
#include
#include
#include
#include
#include
#include
#define ll long long #define inf 0x3f3f3f3f using namespace std; struct position { int l, r; }; struct node { int val; bool flag; }; void pushdown(int root, int l, int r) { if (a[root].flag) { a[root].flag = false; if (l < r) { a[root << 1].flag = true; a[root << 1 | 1].flag = true; a[root << 1].val = a[root].val; a[root << 1 | 1].val = a[root].val; } } } void build(int root, int l, int r) { a[root].flag = true; if (l == r) return; int mid = l + r > 1 ? l + (r - l) / 2 : l; build(root << 1, l, mid); build(root << 1 | 1, mid + 1, r); } void update(int root, int l, int r, int ql, int qr, int val) { if (l > qr || r < ql) return; if (ql <= r && l <= qr) { a[root].val = val; a[root].flag = true; return; } pushdown(root, l, r); int mid = l + r > 1 ? l + (r - l) / 2 : l; update(root << 1, l, mid, ql, qr, val); update(root << 1 | 1, mid + 1, r, ql, qr, val); } void query(int root, int l, int r, int ql, int qr) { if (l == r || a[root].flag) { if (a[root].val) { st.insert(a[root].val); } return; } pushdown(root, l, r); int mid = l + r > 1 ? l + (r - l) / 2 : l; query(root << 1, l, mid, ql, qr); query(root << 1 | 1, mid + 1, r, ql, qr); } int main() { int t = read(); while (t--) { vector
vpos; set
st; int n = read(); for (int i = 1; i <= n; ++i) { int l = read(); int r = read(); vpos.push_back(l); vpos.push_back(r); } sort(vpos.begin(), vpos.end()); int siz = vpos.size(); for (int i = 1; i < siz; ++i) { if (vpos[i] - vpos[i - 1] > 1) { vpos.push_back(vpos[i - 1] + 1); } } sort(vpos.begin(), vpos.end()); vpos.erase(unique(vpos.begin(), vpos.end()), vpos.end()); siz = vpos.size(); build(1, 1, siz); for (int i = 1; i <= n; ++i) { int pos_l = lower_bound(vpos.begin(), vpos.end(), pos[i].l) - vpos.begin() + 1; pos[i].l = pos_l; int pos_r = lower_bound(vpos.begin(), vpos.end(), pos[i].r) - vpos.begin() + 1; pos[i].r = pos_r; update(1, 1, siz, pos[i].l, pos[i].r, i); } query(1, 1, siz, 1, siz); printf("%zu\n", st.size()); } return 0; }

转载地址:http://tqrxz.baihongyu.com/

你可能感兴趣的文章
Objective-C实现OCR文字识别(附完整源码)
查看>>
Objective-C实现odd even sort奇偶排序算法(附完整源码)
查看>>
Objective-C实现page rank算法(附完整源码)
查看>>
Objective-C实现PageRank算法(附完整源码)
查看>>
Objective-C实现pascalTriangle帕斯卡三角形算法(附完整源码)
查看>>
Objective-C实现perfect cube完全立方数算法(附完整源码)
查看>>
Objective-C实现PNG图片格式转换BMP图片格式(附完整源码)
查看>>
Objective-C实现pollard rho大数分解算法(附完整源码)
查看>>
Objective-C实现quick select快速选择算法(附完整源码)
查看>>
Objective-C实现recursive bubble sor递归冒泡排序算法(附完整源码)
查看>>
Objective-C实现recursive insertion sort递归插入排序算法(附完整源码)
查看>>
Objective-C实现RedBlackTree红黑树算法(附完整源码)
查看>>
Objective-C实现redis分布式锁(附完整源码)
查看>>
Objective-C实现reverse letters反向字母算法(附完整源码)
查看>>
Objective-C实现ripple adder涟波加法器算法(附完整源码)
查看>>
Objective-C实现RodCutting棒材切割最大利润算法(附完整源码)
查看>>
Objective-C实现Romberg算法(附完整源码)
查看>>
Objective-C实现round robin循环赛算法(附完整源码)
查看>>
Objective-C实现RRT路径搜索(附完整源码)
查看>>
Objective-C实现rsa 密钥生成器算法(附完整源码)
查看>>