那快把题端上来吧(四)
(从本篇整理起所有代码只提供提交链接,如有需要可私信作者 @qkhm )
[NOIP 2017 提高组] 逛公园
\(\boldsymbol{记忆化搜索,状态优化}\) 。
首先处理出单源最短路 dis[] 。
如果我们直接搜索,记 \((u, k)\) 表示当前位于 \(u\) ,且已经过路径为 \(k\) ,当 \(u=n\) 且 \(k\le dis[n]+K\) 时让答案累加 \(1\) .
我们发现,如果答案路径经过了 \(u\) ,那么 \(k\le dis[u]+K\) 。
所以,我们可以直接令 \(k'=k-dis[u]\) ,当 \(k>K\) 时直接跳出。
再配合记忆化,就可以以 \(O(nK)\) 的空间解决。
但是并不能处理无解的情况,我们发现,当答案经过 \(0\) 环时是有无穷解的。
@CEO dalao 的做法是,正在处理的数组定为 \(-2\) ,如果遇到了 \(-2\) 的状态,那么就是出现了 \(0\) 环,打个标记。
最后扫一遍所有状态,如果造成贡献的状态是遇到 \(0\) 环的,输出 \(-1\) 。
[NOIP 2017 提高组] 小凯的疑惑
\(\boldsymbol{同余最短路}\) 。
打表找规律模板题。
这里提供一种好理解的证明。
如果我们可以拼出 \(x\) ,那么就可以拼出 \(x+b\) , \(x+2b\) , \(x+\cdots b\) 。
我们建出 \(0\cdots b-1\) 的 \(b\) 个同余类,从 \(0\) 开始,每次走到 \((now+a)\bmod b\) 的位置。
因为 \(a\perp b\) ,所以如果 \(\Delta k a \equiv 0 \pmod b\) ,那么 \(\Delta k \equiv 0 \pmod b\) ,即 \(b\mid k\) 。
所以在 \(ab\) 之前,这样一定可以遍历 \(0\sim (b-1)a\) 对 \(b\) 取余的所有 \(b\) 个数。
其中最大的即 \((b-1)a\) 的上一层,也就是大名鼎鼎的 \(ab-a-b\) 。
直接输出即可。
[CSP-S2019] 树的重心
\(\boldsymbol{BIT,dsu\_on\_tree}\) 。
记录我自己的丑陋做法。
首先将重心作为根,然后对于 \(u\ne rt\) ,如果割去一条边后,对位的连通块大小为 \(S\) ,合法的边肯定不能在 \(u\) 的子树nei。
记 \(s_u\) 为 \(u\) 重心为根时的子树大小, \(g_u\) 为 \(u\) 重心为根时儿子中最大的子树大小。
则可以推出 \(n-2s_u\le S \le n-2g_u\) 。
直接使用树状数组计数,然后通过 dsu on tree 容斥掉子树内的信息。
对于根的答案同理,设 \(fir\) 为最大的子树大小, \(sec\) 为次大的子树大小。
如果在非最大子树中割边,那么需要满足 \(S\le n-2fir\) 。
如果在最大子树中割边,那么需要满足 \(2fir-n\le S\le n-2sec\) 。
同样 \(BIT\) 计数即可。
联合猫国
\(\boldsymbol{类倍增}\) 。
记 \(f_i\) 为前 \(i\) 位能合并的最多次数,则有转移 \(f_i=\min_{(j,i]能合并成一个}f_j+1\) 。
现在考虑如何维护合法的 \(j\) 。
记 \(g[i, j]\) 表示与 \([k, i]\) 能拼成一个 \(a_i+j\) 的合法的 \(k\) 。
然后用类似倍增的方法维护 \(g\) ,直接转移,复杂度是能合并成一个数的区间总数,在序列全部相同时取到 \(O(n\log n)\) 。
志愿者招募
\(\boldsymbol{网络流}\) 。
按照时间减点,第 \(i\) 天的点向第 \(i+1\) 天连 \(inf-a_i\) 容量的边,表示最多有这么多人空闲,源点向后流 \(inf\) 的权。
想要最大流,一部分人(流)就要去工作。
我们将不同种的人负责的 \((s, t, c)\) ,从 \(s\) 到 \(t+1\) 连容量 \(inf\) ,权重为 \(c\) 的边。
表示这样的 \(1\) 单位流可以花费 \(c\) 减轻 \(s\) 到 \(t\) 的工作压力。
跑最小费用最大流即可。
方格取数问题
\(\boldsymbol{网络流建模}\) 。
我们只能做选了一个点,另外若干个点必须选之类的限制。
现在我们面临着选了一点,另外若干个点不能选的限制。
考虑转化。
为什么不能按照原有的逻辑做呢?因为我们只能规定某两点不属于一个集合是需要割边的。
我们同时知道,网格图是一个二分图,而只有属于两部的点才会有限制。
所以,我们将左部点与源点相连,边权为点权,右部点与汇点相连,边权为点权。
将限制连上 \(inf\) 边跑最小割即可。
合并神犇
\(\boldsymbol{贪心,单调队列}\) 。
CSP-S 划分原题吗……
设考虑前 \(i\) 个最多能划分出 \(f_i\) 个不降子段,容易发现 \(f_i\) 单调不降(考虑如果降了就和前一个合并成一个块)。
而在划分段数相同的情况下,最后一段一定越小越好。
记 \(s_i\) 为前缀和, \(g_i\) 为最优方案下最后一段的大小。
则 \(f_i=f_j + 1\) , \(j\) 为最大的满足 \(s_i-s_j\ge g_j\) 的下标。
移项得 \(s_i\ge s_j+g_j\) ,单调队列维护即可。
Complicated Computations
见到 \(mex\) ,考虑按照值域扫,判断当前的 \(x\) 是否可能作为答案,即判断是否有区间的 \(mex\) 是 \(x\) 。
如果一个区间 \(mex\) 是 \(x\) ,那么 \(x\) 一定没有出现过, \(x\) 将原序列划分成了若干个段,只有这些极长段的 \(mex\) 可能是 \(x\) 。
然后就成了静态区间 \(mex\) 问题,写主席树即可。
这样的划分段个数是 \(O(n)\) 的,所以复杂度 \(O(n\log n)\) 。
时间仓促,如有错误欢迎指出,欢迎在评论区讨论,如对您有帮助还请点个推荐、关注支持一下

九月训练好题记录
浙公网安备 33010602011771号