《好多题的题解》
「洛谷 P5408」第一类斯特林数·行
根据结论
x¯¯¯n=∑i[ni]xi,
我们只需要求出 x¯¯¯n 的各项系数。显然的 O(nlog2n) 做法就足够过掉洛谷上的原题了,但是我们 OJ 比较卓越,所以得用 O(nlogn) 的做法。
考虑倍增。令 Fn(x)=x¯¯¯n,那么
F2n(x)Fn(x)=Fn(x+n)=n∑i=0[ni](x+n)i=n∑i=0[ni]i∑j=0(ij)xjni−j=n∑j=0xjj!n∑i=j[ni]i!⋅ni−j(i−j)!.
可见 Fn(x+n) 是差卷积形式,O(nlogn) 求出后再和 Fn(x) 卷起来,O(nlogn) 完成倍增。总复杂度 T(n)=T(n/2)+O(nlogn)=O(nlogn)。
「洛谷 P5409」第一类斯特林数·列
你永远可以相信组合意义。
轮换数量的 EGF 为 G(x)=∑i>0(i−1)!xii!,而显然“构成 m 个圆排列”等价于随便拿出 m 个总长为 n 的轮换,再为轮换中的数安排具体的值,最后除掉不同轮换间的顺序。令 R(x)=∑i[ik]xii!,那么
R(x)=Gk(x)k!.
O(nlogn) 快速幂即可。注意 [x0]G(x)≠1,需要位移后进行 ln 运算。
「洛谷 P5395」第二类斯特林数·行
考虑 {nm} 的组合意义:n 个不同的球放入 m 个相同的盒子且盒子不空的方案数。而 m!{nm} 即 n 个不同的球放入 m 个不同的盒子且盒子不空的方案数。所以可以二项式反演求 {nm}:
mn=m∑i=0(mi)⋅i!{ni}⇒{nm}=1m!m∑i=0(−1)m−i(mi)in=m∑i=0(−1)m−i(m−i)!⋅ini!.
好看又好记的式子。而这个通项恰好就是关于 m 这维的卷积形式,所以 O(nlogn) 卷一卷即可。
「洛谷 P5396」第二类斯特林数·列
组合意义嘛。把若干求放入一个盒子的 EGF 为 G(x)=∑i>0xii!=ex−1,令 R(x)=∑i{ik}xii!,那么
R(x)=Gk(x)k!.
还是 O(nlogn) 快速幂。于是你惊讶地发现整个算法与第一类求列的区别只有:初始 G(x) 的系数从 x 的逆元变成了 x! 的逆元。所以这两类数确实是近亲(?)
「HEOI 2016 / TJOI 2016」「洛谷 P4091」求和
f(n)=n∑i=0i∑j=0{ij}2jj!=n∑j=02jj!n∑i=0{ij}=n∑j=02jj!n∑i=0j∑k=0(−1)j−kkik!(j−k)!=n∑j=02jj!j∑k=0(−1)∑ni=0kik!(j−k)!
特殊处理 k=0 和 k=1,其余情况最内层和式可以等差数列求和,得到卷积形式。O(nlogn) 求出卷积再每项带 2jj! 的系数求和即可。
「TC 13444」CountTables
如果只有行上限制就可以直接组合数算,考虑用 DP 化简列上的组合问题。令 f(i) 表示 m=i 时的答案,总数减去不合法方案数,得到
f(i)=(cin)−i−1∑j=1{ij}f(j).
O(n2) 大力算就能过。
「CF 715E」Complete the Permutations
不管怎么说,这个 3400 还是虚高了。
显然的结论:对于已补全的排列 p 和 q,它们的距离为 n 减去置换 σ:pi↦qi (∀i) 中的轮换数量。讨论一对 ⟨pi,qi⟩ 目前的状态:
- ⟨a,b⟩ (ab≠0),将 a,b 视作同一点(缩点),环的数量不改变;
- ⟨0,b⟩ (b≠0),称之为 A 类边;
- ⟨a,0⟩ (a≠0),称之为 B 类边;
- ⟨0,0⟩,称之为 C 类边。
同时又注意到,若 a↦b,b↦c (b≠0) 已经确定,那么无论 a,c 是否为 0,b 都可以被忽略,得到 a↦c。考虑完成上述缩点后该操作的执行:
- A 类边 + A 类边,两者顺序任意,得到新的 A 类边;
- A 类边 + B 类边,不可能执行;
- A 类边 + C 类边,C 放 A 后面,得到新的 C 类边;
- B 类边 + B 类边,两者顺序任意,得到新的 B 类边;
- B 类边 + C 类边,C 妨 B 前面,得到新的 C 类边;
因此,对于 A 类和 B 类边,要不自己连成完整的环,要不直接或间接地被缩入某个 C 类边。注意到以上操作不改变 C 类边的数量,且 ABC 间不相互影响。所以“A 类边构成环,剩下的缩入 C 类边”“B 类边构成环,剩下的缩入 C 类边”以及“C 类边构成环”三个组合问题是独立的。记 A,B,C 分别为三类边在完成所有缩边操作后的数量,考虑它们的方案数关于环数量的 GF:
[xk]GA(x)=A∑i=0(Ai)[ik](A−i+C−1)A−i–––––;[xk]GB(x)=B∑i=0(Bi)[ik](B−i+C−1)B−i–––––;[xk]GC(x)=C![Ck].
解释一下 GA(x):枚举 i 条自己成环,乘上选边和成环方案,其余 (A−i) 条边依次选一条边合并(可能是 A+A 或者 A+C,和剩下的任意边都能合并)。
记 R(x)=GA(x)GB(x)GC(x),设初始时已经有 l 个环确定了,那么 [xn−k]xlR(x) 即为距离为 k 的方案。中途涉及的运算全部暴力,O(n2) 可过。
「HDU 4625」JZPTREE
设某条路径的长度为 d,注意到
dk=k!k∑i=0{ki}(dk),
其中 (dk) 能够被赋予组合意义,对它换根 DP 即可。复杂度 O(Tnk)。
「FJOI 2016」「洛谷 P4609」建筑师
非常自然的想法是将原问题用最大值的位置划分为两个关于最长贪心上升子序列的问题,但不要被这个想法限制了。令 A←A−1,B←B−1,先用除最大值外的 (n−1) 个数构成 (A+B) 个轮换,不放认为轮换中的最大值在第一个的位置,那么把轮换按第一个位置的大小依次放置,就能得到对应长度的最长贪心上升子序列。而所有轮换确定后,最大值 n 自然只有一个位置能放(注意轮换内部形态)。因此,答案为
(A+BA)[n−1A+B].
复杂度 O(nA)−O(1)。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现