牛客小白月赛 73 题解
感谢大家参加牛客小白月赛 73。本场比赛由 氧气少年Kevin 和 罚时大师月色 共同命题。
PDF 题面:点击下载。
A. 最小的数字
本题解法较多:
- 枚举,从 n,n+1,n+2 中,选择较小的、符合条件的输出;
- 直接输出 ⌊3x+2⌋×3。
B. 优美的GCD
本题限制较松,因此解法较多。
例如:直接输出 n,2⋅n 是一种构造方法。
C. 优美的序列
不难发现:如果序列中有两个相同元素,那么一定无解,否则一定有解。
本题解法不止一种,例如:如果有解,排序后输出即可。
D.E. Kevin喜欢零
简单版本思路
维护前缀乘积,使用二分或双指针即可(双指针做法可参考下面的困难版本思路)。
困难版本思路
不难发现:如果 x 的末尾有 k 个后导零,那么 x=p⋅10k,其中 p 不能被 10 整除。
x=p⋅10k=p⋅2k⋅5k。
我们令 f(x)= x 能分解出质因子 2 的数量,例如 f(8)=3,f(6)=1。
我们令 g(x)= x 能分解出质因子 5 的数量,例如 g(25)=2,g(10)=1。
不难发现:x 的末尾有 k 个后导零 ⇔ min(f(x),g(x))=k。
可以维护 f(ai),g(ai) 的前缀和,用此性质,O(1) 计算序列某个子区间乘积的后导零数量。
回到本题,预处理出 f(ai),g(ai) 的前缀和后,枚举右端点 r,使用两个双指针 l1,l2 分别维护合法的最小区间边界和合法的最大区间边界。
例如:n=5,k=3,r=5 时,有:
l1 不能再向右移动,因为如果再向右移动,区间乘积后导零个数就小于 3;
l2 不能再向左移动,因为如果再向左移动,区间乘积后导零个数就大于 3。
对于每个右端点,计算对答案的贡献即可。
F. Kevin的哈希构造
考虑 dp。
令 fi,j,k 表示:当前是第 i 个字符,目前有 j 个位置相同,目前的 hash 表达式累加到了为 k,这样的状态是否可行。
同时,使用前缀数组 prei,j,k 记录每一步选的字符。
转移:
f0,0,0=true
fi,j,k∣=fi−1,j−[c=Si],(j−(c−′a′+1)×bi%p+p)%p,其中 c 指当前枚举的 Ti 应放的字符。
最后,如果 fn,k,hash=false,说明无解;否则,由前缀数组逐个输出字符即可。
G. MoonLight 的冒泡排序难题
不难发现,while 循环执行次数 = 后面有更小元素的元素数量。换句话说,while 循环执行次数 =∑i=1n[∃j>i 满足 pj<pi] 。
因此,求 ∑i=1n[∃j>i 满足 pj<pi] 的期望值即可。
思路1
hint1: 考虑期望的定义式:E=总事件数有效事件数。这里,总事件数 =n!。
hint2: 考虑单个元素对有效事件数的贡献。
hint3: 构造方式:从小到大枚举元素,不断构造新的排列。
我们考虑元素 i 在长度为 n 的排列的贡献为:
我们发现元素 i 的贡献跟前 i−1 元素的位置有关,于是我们先构造 i−1 个元素的排列。
在构造长度为 i 的排列时,我们可以发现,它是由长度为 i−1 的排列插空得出。
长度为 i−1 的排列有 i 个空隙,只有前 i−1 个空隙对总事件数有贡献,产生的贡献是 (i−1)!⋅(i−1) 。
由于排列总长度为 n,剩下 n−i 个元素随便放,方案数是 Ann−i。
于是可以得到,元素 i 对总事件数的贡献为:(i−1)!⋅(i−1)⋅Ann−i。
进一步化简,由 Ann−i=i!n! 代入得 n!⋅ii−1。
因此,元素 i 对总事件数贡献为:n!⋅ii−1。
因此,我们设 fi= 前 i 个元素对于长度为 n 的排列的贡献,那么有:fi=fi−1+n!⋅ii−1。
长度为 n 的排列的美丽值的期望 E(n)=n!fn。
不难发现可以令 gi=gi−1+ii−1,此时长度为 n 的排列的美丽值的期望 E(n)=g(n)。
预处理 g(i),直接回答询问即可。
思路2
假设当前排列长度为 i,美丽值的期望为 fi,
现在随机插入一个新的元素 i+1,
这个元素比之前所有的元素都大,
且在 i+1 个可以插入的位置的可能性是均等的,但只有插入的位置不是最后才对美丽值产生贡献。
因此 fi=fi−1+ii−1。
预处理前缀和数组后,直接回答询问即可。