Loading

那快把题端上来吧(四)

(从本篇整理起所有代码只提供提交链接,如有需要可私信作者 @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\)

Record

[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\)
直接输出即可。

Record

[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\) 计数即可。

Record

联合猫国

\(\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)\)

Record

志愿者招募

\(\boldsymbol{网络流}\)
按照时间减点,第 \(i\) 天的点向第 \(i+1\) 天连 \(inf-a_i\) 容量的边,表示最多有这么多人空闲,源点向后流 \(inf\) 的权。
想要最大流,一部分人(流)就要去工作。
我们将不同种的人负责的 \((s, t, c)\) ,从 \(s\)\(t+1\) 连容量 \(inf\) ,权重为 \(c\) 的边。
表示这样的 \(1\) 单位流可以花费 \(c\) 减轻 \(s\)\(t\) 的工作压力。
跑最小费用最大流即可。

Record

方格取数问题

\(\boldsymbol{网络流建模}\)
我们只能做选了一个点,另外若干个点必须选之类的限制。
现在我们面临着选了一点,另外若干个点不能选的限制。
考虑转化。
为什么不能按照原有的逻辑做呢?因为我们只能规定某两点不属于一个集合是需要割边的。
我们同时知道,网格图是一个二分图,而只有属于两部的点才会有限制。
所以,我们将左部点与源点相连,边权为点权,右部点与汇点相连,边权为点权。
将限制连上 \(inf\) 边跑最小割即可。

Record

合并神犇

\(\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\) ,单调队列维护即可。

Record

Complicated Computations

见到 \(mex\) ,考虑按照值域扫,判断当前的 \(x\) 是否可能作为答案,即判断是否有区间的 \(mex\)\(x\)
如果一个区间 \(mex\)\(x\) ,那么 \(x\) 一定没有出现过, \(x\) 将原序列划分成了若干个段,只有这些极长段的 \(mex\) 可能是 \(x\)
然后就成了静态区间 \(mex\) 问题,写主席树即可。
这样的划分段个数是 \(O(n)\) 的,所以复杂度 \(O(n\log n)\)

Record

posted @ 2025-09-03 21:30  qkhm  阅读(14)  评论(0)    收藏  举报