CF1174E - Ehab and the Expected GCD Problem 题解
我太菜了/yun 我通篇抄题解/yun 我是傻逼/yun
首先莽算是不行的,那样就是莽夫,而我们应该集《智慧和勇敢》于一身。观察得出结论:显然对第一个数 \(x=\prod p_i^{\alpha_i}\) 的 \(f\) 值上限为 \(\sum \alpha_i\),而它显然是能取到的。于是第一个数的 \(\sum\alpha_i\) 值需要尽可能大,贪心地取 \(p=[2]\)。那还可能有别的相等的吗?可能把其中一个 \(2\) 改成 \(3\)(只要 \(\leq n\)),再多 \(3\) 就不可能了,因为 \(3^2>2^3\)。\(5\) 以上也不可能有了,因为 \(5>2^2\)。
那么我们就考虑如何计算方案数。显然每次改变 \(\gcd\) 是新加入一个数使得当前 \(\gcd\) 的 \(2\) 或 \(3\) 的指数 \(-1\)。很自然的想到一个 DP:\(dp_{i,j,k}\) 表示考虑到第 \(i\) 位,当前 \(\gcd\) 是 \(2^j3^k\) 的方案数。这样状态数是线对的,不用愁。然后我就不会了,看了题解发现我是傻逼。
我当时想的是,枚举上一个改变 \(\gcd\) 的点,然后用组合数转移。那这样就是平方对数,然后 \((i+j)!\) 的形式又拆不开,不好优化。但实际上我们只需要向 \(i-1\) 转移即可……分为三类:\(\gcd\) 不变、\(2\) 的指数变、\(3\) 的指数变。每类在 DP 值前面乘的系数显然是位置 \(i-1\) 可以填的数的个数,这个很好算就是了,可能要容斥一下,\(n\) 以内 \(x\) 的倍数个数就是 \(\left\lfloor\dfrac nx\right\rfloor\)。所以说有的时候 DP 感觉不可优化了,这时候大概率不是我的相关水平不够,而是转移思路和状态设计需要改一改了……
代码异常好写,复杂度线对。
然后看到题解区有线性做法,去 read 了一下,这不是我想这题的时候想了一段时间然后误认为假了的做法之一吗?
我们考虑枚举整个 \(\gcd\) 变化情况,如果全 \(2\) 那显然只有一种,如果有 \(3\) 那就枚举最后一次出现 \(3\) 的位置,是对数的。那考虑对每一种情况算方案数。
我们假设已经固定了改变 \(\gcd\) 的 \(\log\) 个关键数,显然每个关键数序列是等价的,最后简单乘法原理一下即可。然后我们需要算非关键数的合法排列方案数。显然每个数所能在的区域是一个后缀。因为这个位置比较灵活,就像细胞内的某结构一样,我们考虑这样一个常见思路,把数们一个一个扔进去然后把所有数在被扔进去的时刻可插入的空隙数乘起来。那么后缀不同的显然分为 \(\log\) 类,每类数一起插(顺序无所谓)的话,那就是一个等差数列求积,这个阶乘阶乘逆元即可。于是这一部分是二次对数的。
然后阶乘逆元也可以线性求,就做到了线性。