【比赛日志】USACO 2020 US Open Contest, Platinum

USACO 2020 US Open Contest, Platinum

Problem 1. Sprinklers 2: Return of the Alfalfa

考虑一个合法的解,容易发现,种植C的与A的之间有一条从左上角到右下角折线作为分界线。

对于一个分界线来说,合法解的数量为\(2^{(空余的格子数量-转折的数量)}\)

我们设当前处于\((i,j)\)上方的横向折线,它的方案数为\(f_{i,j}\);设当前处于\((i,j)\)右方的折线,它的方案数为\(g_{i,j}\)。可以有以下转移式:

\[f_{1,1}=g_{1,1}=2^{空余格子数} \\ f_{i,j}\to f_{i+1,j} \quad (i < n) \\ f_{i,j}/2 \to g_{i+1,j} \quad (i \le n, a_{i,j}\ne W) \\ g_{i,j} \to g_{i,j+1} \quad (j < n) g_{i,j}/2 \to f_{i, j+1} \quad (j \le n) \]

答案即为\(f_{n,n+1}+g_{n+1, n}\)

  • +50min:调试完,过了所有样例。上传:AC

Problem 2. Exercise

+100min:实在想不到怎么优化了,开始写代码。

初步想法

计算出所有的“环”,则所有环的长度的lcm即为要经过的步数。

固定所有“环”,设长度为\(i\)的环有\(a_i\)个,则满足要求的排列的数量为

\[\begin{aligned} &\frac{n!}{\prod_{i=1}^n (i!)^{a_i}} / \prod_{i=1}^n{a_i!} * \prod_{i=1}^n{{A_i}^{a_i}} \\ =&\frac{n!}{\prod_{i=1}^n i^{a_i}{a_i!}} \end{aligned} \]

其中,\(A_i = (i-1)!\)表示\(i\)个数的排列恰好形成一个“环”的方案数。(相当于一个有向的圆排列)

设所有“环”长均为\(x\)的因数的方案数为\(f_x\),所有“环”长的lcm为\(x\)的方案数为\(g_x\),有:

\[g * 1 = f \iff g = f * \mu \]

只需要计算出\(f\)即可计算出\(g\)

如何计算\(f\)?用朴素DP的话,需要存\(lcm,i,a_i,\sum_i ia_i\),复杂度是\(O(n^4)\)的(或者\(O(n^3\log n)\))。

(+100min)……刚刚发现了一件事:所有lcm的数量可能是极大的……根本没法枚举……【自闭】

由于答案要求的是所有步数的乘积,那么能不能求出步数中恰好被\(p^{k}\)整除的个数呢?

若要求出\(g\),则可以枚举所有\(p\)的幂次不超过\(k\)的数进行转移,当\(k'=k+1\)时,直接在原来的背包数组中添加\(p\)的幂次为\(k\)的数即可。

总复杂度应该是\(O(n^4)\)的。

小小优化

考虑用背包的方法处理转移式:设\(f_{i,j}\)表示当前所有“环”长的lcm为\(i\),已经处理了\(j\)个数的方案数。
当环长\(=k\)时,对每一个\(\bmod k\)的剩余系做一个背包即可,复杂度为\(O(n^2)\)

总复杂度是\(O(n^3)\),仍然有点高。

我们考虑计算所有数均为\(k\)的因数的方案,只需要枚举所有\(k\)的因数即可,可以用一维\(g_i\)表示。复杂度是\(O(\sigma_0(k)n)\)的。

总复杂度应该是\(O(n\sum_{k=1}^n\sigma_0(k))=O(n^2\log n)\)的,但是对于\(n=7500\)似乎还是有些无力……

再进一步?

我们考虑一个玄学优化:对于\(k\),我们从\(k/p\)转移过来,其中\(p\)是一个\(k\)的素因数,不妨设是最小的。然而,这也只能将需要计算的数目从\(68093\)优化到\(24245\),还远远不够。

束手无策了……先写起来吧……

posted @ 2021-06-17 20:46  frank3215  阅读(66)  评论(0)    收藏  举报