2025.4.17 近期题目整理
nfls Rikka with Shortest Path
不算难题,只是一些 trick 忘记了,加强一下记忆。
-
最短路问题的常见处理方法:按照距离分层,然后逐层 dp。
-
正着 dp 困难,可以倒着。
手法细节:如果不是一直在对一个数做加法,不能使用分支预测优化 smr 取模。
调试好方法:将题目中给定的常量 \(10^6\) 手动改为大小能接受手动模拟的数。
P10433 [JOISC 2024] 棋盘游戏 (Day2)
超级炫酷图论。
假了 \(2\) 处。
最后一步根号分治很奇妙。
对于 \(k\leq B\),暴力,这个暴力细节很多,点的有效 dp 范围不一定为 \([1,{n\over k}]\),可能整体会加上一个偏移量,这个东西可以通过预处理实现。
对于 \(k\gt B\),由于贡献函数是个至多 \(k\) 段的函数,且函数上凸,所以可以将每一段线段看成直线,然后就能轻松求解。
启示:
重要思想:最优化问题,可以进行不优转移,但要保证一定能进行最优转移。如果觉得原问题不好做,不妨放宽限制。
请一定要多分讨各种情况。
为了验证性质正确性,可以多观察样例。
[ARC092F] Two Faced Edges
简单题,但是带来很多想法。
\(n=10^3,m=2\times 10^5\)
题目转化为求有向图删边 \((u,v)\) 后询问 \((u,v)\) 之间是否存在路径。
-
炫酷 dfs
枚举起点后,先 dfs 一遍,然后翻转出边数组,再 dfs 一遍,如果两次中 \(v\) 的深度均为 \(1\) 则不合法,\(O(nm)\)。 -
缺一分治
先求删点后的传递闭包,然后暴力枚举路径上最后一条边即可,\(O(nm)\)。 -
前后缀合并
删掉一个点的所有入边,求出一个点的所有出边的前缀和后缀的传递闭包,然后二者求或即可,\(O({nm\over w})\) -
优化前后缀合并
这里仅说明前缀的做法。枚举 \(u\) 的出边 \(v\),从 \(v\) 开始 dfs,但是使用 set 和 lower_bound 快速找到下一个未被访问过的点,也可以使用 bitset(只能 bfs),\(O(n^2\log n)\) 或 \(O({n^3\over w})\)
启示:
仅仅有一个特殊,可以使用 缺一分治/前后缀合并
传递闭包允许动态加点,添加的复杂度是 \(O({n^2\over w})\) 方法如下:
struct concave{
bitset<N+5> e[N+5];
void add(int u) {
e[u]|=ve[u];
for (int i{1};i<=n;++i)
if (e[u][i]) e[u]|=e[i];
for (int i{1};i<=n;++i)
if (e[i][u]) e[i]|=e[u];
}
}f;