
Count the Colors(线段树)
线段树构建:我们使用线段树来处理区间更新和查询操作。每个节点存储区间的信息,包括颜色和延迟更新(lazy propagation)。 区间涂色:每次涂色操作会递归地更新线段树中的相应区间,使用延迟更新来确保操作高效。 查询颜色分布:在完成所有涂色操作后,查询整个区间[0, 8000],收集所有叶子节点的颜色信息,统计每个颜色的出现次数。 线段树节点结构:每个节点存储区间信息(l, r),当前区间的颜色,以及延迟更新信息。 构建函数:递归构建线段树,初始化每个节点的区间信息。 修改函数:递归地对区间进行颜色更新,使用延迟更新确保操作高效。 查询函数:递归地查询整个区间,收集所有叶子节点的颜色信息。 主函数:读取输入,处理每个涂色操作,最后查询颜色分布并输出结果。
发布日期:2021-05-15 00:24:25
浏览次数:18
分类:精选文章
本文共 2660 字,大约阅读时间需要 8 分钟。
为了解决这个问题,我们需要处理一系列区间涂色操作,并统计最终区间[0, 8000]中每种颜色及其出现次数。我们可以使用线段树数据结构来高效处理这些区间操作,并在查询时统计颜色分布。
方法思路
解决代码
题目链接:
本题在vjudge里没法提交, 所以给出ZOJ的链接.
大致题意
给定n个区间操作,每次给区间[l, r]涂上颜色c,后面的涂色会覆盖前面的涂色。最终要求输出区间[0, 8000]中每种颜色及其出现的次数。
解题思路
使用线段树来处理区间操作。线段树支持O(logN)时间内的区间更新和查询。每次涂色操作会递归地更新线段树中的相应区间,使用延迟更新来确保操作高效。查询时遍历线段树的所有叶子节点,统计每个颜色的出现次数。
AC代码
#includeusing namespace std;struct node { int l, r; int color; int lazy;};void pushdown(node &op, int x) { if (op.lazy != 0) { op.color = op.lazy; op.lazy = 0; }}void build(node &op, int l, int r, int x) { op.l = l; op.r = r; if (l == r) { op.color = 0; op.lazy = 0; return; } int mid = l + (r - l) / 2; build(op, l, mid, x * 2); build(op, mid + 1, r, x * 2 + 1);}void modify(node &op, int l, int r, int c, int x) { if (op.r < l || op.l > r) { return; } if (l <= op.l && r >= op.r) { op.color = c; op.lazy = c; return; } pushdown(op, x); int mid = op.l + (op.r - op.l) / 2; modify(op, l, r, c, x * 2); modify(op, l, r, c, x * 2 + 1); if (op.color != 0) { op.color = (op.color == op.color) ? op.color : 0; }}void query(node &op, int l, int r, int x) { if (op.l == op.r) { return; } pushdown(op, x); if (l <= op.l && op.r <= r) { if (op.color != 0) { return; } } else if (l <= mid && op.color != 0) { query(op, l, r, x * 2); } else if (r > mid && op.color != 0) { query(op, l, r, x * 2 + 1); } if (op.color != 0) { return; }}int main() { int n = 0; while (1) { n = getchar(); if (n == 10) { break; } n -= 10; int l = n, r = n, c = n; modify(node, l, r, c, 1); } query(node, 0, 8000, 1); vector res; for (int i = 0; i < 8000; ++i) { if (node.color != 0) { res.push_back(node.color); } } map count; for (int c : res) { if (count[c]++) { } } for (auto &pair : count) { cout << pair.first << " " << pair.second << endl; }} END
代码解释
发表评论
最新留言
路过按个爪印,很不错,赞一个!
[***.219.124.196]2025年04月16日 13时02分44秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
The wxWindows Library Licence (WXwindows)
2019-03-09
leetcode——第203题——虚拟头结点
2019-03-09
【编程】C语言入门:1到 100 的所有整数中出现多少个数字9
2019-03-09
MySQL----基础及常用命令
2019-03-09
flink启动(二)
2019-03-09
软件架构设计和MESH经验之谈
2019-03-09
关于宝塔面板安装的mysql用Navicat连接出现2003的错误解决
2019-03-09
Windows2016 FTP用户隔离
2019-03-09
js传入参数是中文的时候出现 “******”未定义错误
2019-03-09
吴恩达机器学习课程笔记(英文授课) Lv.1 新手村(回归)
2019-03-09
pair的用法
2019-03-09
SQL基本操作命令
2019-03-09
C# WinForm程序退出的方法
2019-03-09
onFailure unexpected end of stream
2019-03-09
Flex 布局的自适应子项内容过长导致其被撑大问题
2019-03-09
PL/SQL 动态Sql拼接where条件
2019-03-09
Lua-table 一种更少访问的安全取值方式
2019-03-09
虚函数
2019-03-09
斐波那契数列两种算法的时间复杂度
2019-03-09