模拟42 题解
A. 世界线
毒瘤出题人,bitset题卡空间。
于是将所有的点分成两份,做两次拓扑排序,bitset只用开一半,空间就能够了。
B. 时间机器
似乎是很显然的贪心,然而没想到。
只会打更加显然的网络流暴力。
按左端点排序,set维护一下不断取后继就行了,当没有后继即为无解。
C. 密码
将所有合法的组合数打个表,找一下规律。
然后整个机房的屏幕中都出现了奇怪的01三角形。
然而并没有用。
这个数据范围,正解显然是数位dp。
将组合数拆为一个阶乘除两个阶乘的形式,我们只关注p这个质因子出现的次数。
已经拆为阶乘了,就去想如何表示一个阶乘中p因子出现的个数。
这个是见过很多遍的题,就是不断除p相加。
于是我们将组合数中的n,m,n-m分别拆为p进制(这个太难想到了)。
n!中质因子p的个数其实就是
枚举考虑从最高位开始的$0$~$log_p^n-1$位,p进制表示下,这几位表示的数 的和,
注意p的指数要上下相减,所以考虑m与n-m相加的过程,
组合数$C_n^m$中p出现的次数,其实就是m与n-m,在p进制下作加法,进位的次数。
问题转化为求
两数相加不大于n,且在p进制下进位不少于k次的方案数。
于是直接数位dp(暴力记忆化搜索),
状态要设为四维,$dp(i,j,0/1,0/1)$表示从考虑最高位到第i位,进位了j次,第i位是否被进位,从最高位到第i位是否受到最大值l的限制。
dp的第三维看似没有必要,但如果不考虑,真的无法写出转移。
暴力$p^2$枚举下一位的两个数填什么,可以做到80分。
如果发现了特殊的性质:枚举的过程中其实加的都是重复的东西。
将这个系数求出来,大概是公差为1的等差数列加公差为0的等差数列(其实就是简单乘积)。
复杂度变为状态数。
应当注意的是,在普通的数位dp(dfs做法)中,我们无需对状态的最后一维(是否受最大值限制)进行记忆化。
因为在通常的搜索树中,它只会被搜索一次,这个记忆化是没有意义的。
然而本题考虑的是两数加和,有/无进位两种情况,都由下一位的同一个受限制的状态转移,不记忆化会使复杂度飙到$O(n)$级别。