G - Counting Buildings
简要题义
一个排列的 \(L(P)\) 为 \(\sum_{i=1}^n [premax(i)=P_i]\),即前缀最大值为自身的位置数,\(R(P)\) 同理为后缀最大值。
有多少个排列使得 \(L(P)-R(P)=k\)
题解
假设 \(n,k\) 是同阶的。
我们从 \(n\) 到 \(1\) 依次插入数,考虑朴素的 DP:设 \(f_{i,k}\) 表示当前填了 \([n-i+1,n]\) 这些数,\(L-R=k\) 的方案数。当插入一个数时,将其放在首位 \(L\) 一定增加 \(1\) ,放在末尾,\(R\) 一定增加 \(1\) ,其余位置,\(L,R\) 不变,有转移:
设 \(F_i=\sum [x^k] f_{i,k}\),我们最终求 \([x^k] F_n\) 。
该状态转移可以写成多项式形式,即 \(F_i=(x+(i-2)+\frac{1}{x}) F_{i-1}\) ,那 \(F_n=\prod_{i=2}^n (x+(i-2)+\frac{1}{x})=\prod_{i=0}^{n-2} (x+i+\frac{1}{x})\) 。
负系数不太好维护,改成 \([x^k] F_n=[x^k]\prod_{i=0}^{n-2} (x+i+\frac{1}{x}) = [x^{k+n-1}] \prod_{i=0}^{n-2} (x^2+ix+1)\)。
两个幂次为 \(n\) 的多项式乘法可以在 \(O(nlogn)\) 的复杂度下完成。运用启发式合并的思想,我们每次找到当前次数最小的两个多项式做乘法,每个多项式最多被计算 \(O(logn)\) 次,总的复杂度为 \(O(nlog^2n)\) 。
当然,可以使用分治模拟启发式合并的过程,保证每一个搜索层下,现有多项式的次数都尽可能的平均,也就是模拟了启发式合并。
多项式乘法用 NTT 。
参考代码(分治做法)