8.20 教你如何飘飘欲仙
上一周周五的时候某人觉得把 tag 写上会更好,我觉得说的道理。
走迷宫
一个琪露诺在 \(n(1\le n\le 10000)\) 点 \(m(0\le m\le 1000000)\) 边的有向图上从 \(s\) 开始随机游走,问走到 \(t\) 的经过边数的期望。如果存在能从起点走到且路径上与从这个点出发都不能到达终点的点,输出
INF
。
限制:图上强连通分量大小不超过 \(100\)。
部分分:图是一个拓扑图。
tag:期望,强连通分量,高斯消元,拓扑序
首先思考拓扑图怎么做。这是一个很经典的问题。设 \(f_i\) 表示从点 \(i\) 走到点 \(t\) 所用的步数,集合 \(E_i\) 为点 \(i\) 所有出边,那么我们可知 \(f_t = 0\),而且:
直接按拓扑序遍历递推即可。
然后思考如果 \(O(n^3)\) 能过怎么做。对于每个点,同样有 \(1\) 等式成立。因为有环形结构,且 \(1\) 式成立,等式的意义就由递推变成了方程组。直接高斯消元是 \(O(n^3)\) 的。
然后我们把这两个做法结合起来,缩点后跑拓扑序,若我们现在的点是 \(u \in S\),有边 \(u \rightarrow v\),那么我们分类讨论:
- 若 \(v \in S\),那么 \(u \rightarrow v\) 属于环状结构的一部分,将 \(v\) 也放入方程组中。
- 若 \(v \not\in S\),这时由于我们按照拓扑序递推,\(dfn_v\) 一定大于 \(dfn_u\)。那么在 \(u\) 的方程中加入常量部分即可。
由于有强连通分量大小不大于 \(100\) 的限制,这个做法可以通过。
The Best Teams
有 \(n\) 个人,每个人 \(i\) 有年龄 \(a_i\) 与技能值 \(s_i\),现在限制按 \(s_i\) 排序后相邻的两个人不能同时入队。有 \(Q\) 次询问,每次询问给出限定年龄 \(s\) 与限定人数 \(p\),要求选出不超过 \(p\) 个人,使其技能值之和最大,且年龄不大于 \(s\)。
\(1 \le n,q \le 300000\)
tag:离线问题,简单数据结构
限定年龄实际上是一段一段的,每一段都在一个相同的集合里选人。于是考虑离线之后按限定年龄大小排序,然后将队员由年龄从小到大加入选人的集合。
思考现在有选人集合,有一些能力相邻的人不能同时选(为什么是有一些?因为题目的限制是 \(n\) 个人全在队里的情况),如何选人使技能值之和最大。那么我们一定是贪心选择最大的,然后把不能同时选的那一个排除,然后再重复。
思考如何加速这个过程。对于选人集合中一段在原序列中相邻的人,我们可以前缀和预处理出答案。但是如果只是单纯统计出一段段区间枚举,仍然会超时。区间的连接和合并很简单,使用并查集即可。问题在于第二个限制,对选出的人数有要求。于是我们分块之后按起点把区间塞进块里,然后一个一个块找就可以了。时间复杂度 \(O(n\sqrt n)\),跟 \(m\) 无关,因为反正我们都需要从小加到大。
监狱
n 个点的树,树上有 m 个人,一次可以让一个人沿一条边走到另一个点,但是不能走到其他人所在的点。现在给你 m 个人的初始点位(保证互不相同),与 m 个人的终点(保证互不相同),求有无一种方案,使每个人都能沿最短路径到终点。(n,m<=1e5)
tag:图的构建,tarjan 找环
没做出来,果然技不如人。
主要是转图的另一步没有想到。实际上图就是由元素和关系(无向图为无向关系,有向图为有向关系)组成的一种结构。
思考
路径分三种:上行,下行,折线。分类讨论不同种类的线与线的关系实在太复杂了点。直接思考构造解不太可行,我们尝试思考线与线的约束关系。
发现线与线只有两种关系,即先走和后走。如果有向路径 \((u,v)\) 必须要在 \((u',v')\) 之前先走,那么路径 \((u,v)\) 必定阻碍的路径 \((u',v')\),且这种阻碍可以通过行走解决。那么就是 \((u,v)\) 中的一段路被 \((u',v')\) 包含。如果我们归纳规律,实际上就是 \(u\) 被 \((u',v')\) 包含。
如果有向路径 \((u,v)\) 必须要在 \((u',v')\) 之前后走,同理可得这意味着 \((u,v)\) 走完后会阻碍 \((u',v')\),即 \(v\) 被路径 \((u',v')\) 包含。
然后不会了。
正解
考虑靠约束关系建边。边的意义 \(u \rightarrow v\) 即 \(u\) 要在 \(v\) 之前走。对于所有在路径 \((u_i,v_i)\) 上的起点 \(u_j\),我们从 \(j\) 向 \(i\) 连边,对于路径上的终点 \(v_j\),我们从 \(i\) 向 \(j\) 连边。由于剖分后实际上是向一个区间连边,因此可以优化建图。无解条件即为图中存在环。
错误拼写
一个由小写字母组成长为 \(n\) 的字符串 \(S\),有 \(m\) 组限制,第 \(i\) 组限制形如 \(a_i,b_i\),表示删掉第 \(a_i\) 个字母的字符串不大于删掉第 \(b_i\) 个字母的字符串字典序。求原字符串方案数量。
\(n,m \le 500000\)
tag:限制转换,动态规划
实际上做完转换就不难。也侧面说明了发掘题目条件的重要性。
发现这个约束很不优美,尝试发现其中规律。然后可以得出实际上的字典序比较为这样(不妨设 \(a<b\),如果 \(a>b\) 实际上就是反着来。):
不小心把 \(b\) 多画了一格。。。将就地看吧
那么我们得出了真正的限制:\(S(a + 1,b) \le S(a,b - 1)\)。我们无法直接对区间进行约束,于是我们把限制 \((a,b)\) 平摊到字符上得出:若设字符 \(S_i\) 与 \(S_{i+1}\) 的大小关系为 \(g(i) \in \{<,>,=\}\),那么区间 \([a,b)\) 中第一个 \(g(i) = \{<\}\)。
于是我们动态规划,设 \(f_{i,j}\) 表示枚举到了 \(i\),且最后一个字母为 \(j\),简单转移即可。
今天没做多少题,因为感冒了,两个鼻孔里的水冒出来的速度比喝下去的快,脑袋晕晕的。。。各位注意出了汗及时换衣服,不要傻乎乎地还跑到空调下面吹。。。睡觉去了(lll¬ω¬)