当前位置: 首页 > news >正文

[NOI2014] 购票

NOI2014 购票 - 洛谷 P2305

先考虑序列上的情况,令 \(f_u\) 表示从 \(u\)\(1\) 的最小代价。

下面的 \(s\) 是题目中 \(s\)前缀和,前缀和对于每个 \(u\),都可以二分找到一个 \(L\),使得 \(L\) 是最小的 \(s_u - s_{L - 1} \le l_u\),那么 \(f_u = \min\limits_{v = L}^{u - 1} \{ f_v + (s_u - s_{L - 1})p_u \} + q_u\),显然是一个斜率优化的形式。因为是从区间转移过来,可以使用分治/线段树套单调栈的做法。还有一点: \(p_u\) 不单调,需要使用二分。


现在丢到树上,我们可以想办法往序列上靠。这里介绍两种方法。(题解有 \(4\) 种)

\(s\) 变成了 \(u\)\(1\) 的边权之和。

F1

序列上可以分治,在树上自然可以点分治

特别的一点是,这时一棵有根树。找到点分中心后,就用 \(1\) 所在的那棵子树对剩下的部分进行转移,按照 \(s\) 排序后后,双指针转移即可。

时间复杂度:\(O(n\log^2n)\)

F2

首先有十分暴力的做法:树链剖分,但这玩意就 \(3\log\) 了,听说也能搞过。但是我们还要寻找一个更加优秀的方式,将树转化为序列。

这里有一个十分神奇的 trick:使用 出栈序

具体的,我们按照离开 \(u\) 子树的时间对 \(u\) 进行排序,设 \(u\) 的排名为 \(rnk_u\)。DFS 求解 \(f_u\) 时,仍然可以倍增求出那个最浅的 \(L\)\(L\)\(u\) 的祖先),那么直接从区间 \([rnk_u, rnk_L]\) 转移过来即可。

证明如下: 区间内的点 \(v\) 分为两类

  • \(v\)\(u\) 的祖先,那么本来就可以转移到 \(u\)
  • 否则 \(v\) 此时肯定还没有被访问到(\(rnk_v > rnk_u\)),转移过来就是没转移。

于是沿用序列的做法即可。

时间复杂度:\(O(n \log^2 n)\)

可能你会有疑问:用线段树套单调栈,直接加入,\(d\) 有单调性吗?答案是没有,但是你查询的时候有就行了。或者你可以写李超树。

总结

序列问题还是比较好解决的,就是要想尽办法变成树上问题。这题有一个出栈序的神秘 trick 可以轻松解决这个问题。

http://www.jsqmd.com/news/73054/

相关文章:

  • 解码IPC-管道与信号 - 指南
  • 软件工程学习日子2025.12.11
  • 12月11号
  • 4
  • 阅读笔记六:编码与重构
  • 12月10号
  • 大夏龙雀DX-WF25(ESP32-C2-H2) mixly开发
  • 线段树
  • C++多线程性能优化实战:从互斥锁到无锁编程完全指南
  • Airflow - override()
  • React zustand todos案例(带本地存储localStorage、persist)todoStore.ts - 详解
  • SpringBoot 如何构建零拷贝:深度解析零拷贝科技
  • SpringBoot 如何构建零拷贝:深度解析零拷贝科技
  • MySQL基础语法复习笔记(含完整代码示例+新手实操指南) - 教程
  • Thinkphp6---关联查询
  • Unity 游戏启动器
  • Day28综合案例--双开门
  • Swift-Prometheus 库因指标名称与标签未净化导致的指标劫持漏洞详解
  • 一种融合身份证识别与炫彩活体检测而生的人脸核身技术,实现无感身份强认证
  • c++实验五
  • Linux命令记录
  • useradd、usermod、userdel命令详解
  • PRD太难写?AI生成的产品需求文档,到底能不能用?
  • 无监督通用流数据异常检测新方法SEAD
  • [ROI 2017] 前往大都会 (Day 1)
  • FreeRTOS任务卡死在prvTaskExitError
  • 2025年12月北京GEO服务商推荐 - 品牌2025
  • 2025 最新广州瑜伽馆TOP5 评测!优质瑜伽培训机构年度榜单发布,品牌沉淀+国际认证,传统瑜伽赋能身心平衡新生态 - 全局中转站
  • 《程序员修炼之道:从小工到专家》笔记8
  • 记录生活系统|记录美好|健康管理|基于java+Android+微信小程序的记录生活系统设计与构建(源码+数据库+文档)