1 条题解
-
0
好的,我们先一步步分析这个问题。
题意整理
- 长度为 (n) 的 交错序列:仅由 0 和 1 组成,没有相邻的 1。
- 对于一个这样的序列,设 0 的个数为 (x),1 的个数为 (y),满足 (x + y = n)。
- 序列的特征值 = (x^a y^b)。
- 求所有长度为 (n) 的交错序列的特征值之和,结果对质数 (m) 取模。
- 注意 (0^0=1)。
第一步:转化为组合模型
没有相邻的 1,就是经典的 无相邻 1 的 0-1 串 计数问题。
设 (y) 个 1,那么 1 之间有 (y-1) 个间隙(不允许相邻,所以每两个 1 之间至少 1 个 0),还需要考虑首尾也可以有 0。把 (y) 个 1 排好,它们之间有 (y+1) 个空隙(包括首尾),在这些空隙中放入 (x = n-y) 个 0,每个空隙的 0 个数 (\ge 0),且 0 的总数固定为 (n-y)。
放 0 的方案数 = 将 (n-y) 个相同球放入 (y+1) 个盒(可空)的方案数,即: [ \binom{(n-y) + (y+1) - 1}{y+1 - 1} = \binom{n-y + y}{y} = \binom{n-y+1}{y} ] 检验:设 1 的个数 (y),0 的个数 (x = n-y),将 (x) 个 0 分配到 (y+1) 个空隙(可空): [ \binom{x + (y+1) - 1}{(y+1)-1} = \binom{x + y}{y} = \binom{n}{y} ] 等一下,这样不对,我们仔细算。
我们要求的是 (x) 个 0 放入 (y+1) 个空隙(可空),方案数是 (\binom{x + y+1 - 1}{y} = \binom{x+y}{y} = \binom{n}{y})。
这似乎是一个熟悉的结果:无相邻 1 的 0-1 串数量与组合数 (\binom{n-y+1}{y}) 的关系。
实际上,经典结论:
无相邻 1 的长度为 (n) 的 0-1 串,若含 (y) 个 1,则方案数 = (\binom{n-y+1}{y})。推导:把 (y) 个 1 放好,它们之间有 (y-1) 个空隙必须放至少 1 个 0(避免相邻),所以先在这 (y-1) 个空隙中各放 1 个 0,用掉 (y-1) 个 0,剩下 (x - (y-1) = n-y - y + 1 = n - 2y + 1) 个 0 可以任意分配到 (y+1) 个空隙(包括首尾)。
将 (n-2y+1) 个不可区分的 0 放入 (y+1) 个可空盒子:(\binom{(n-2y+1)+(y+1)-1}{y} = \binom{n-y+1}{y})。所以: [ \text{固定 } y \text{ 的方案数} = \binom{n-y+1}{y} \quad (\text{若 } n-y+1 \ge y \text{ 即 } y \le \lfloor \frac{n+1}{2} \rfloor) ] 否则为 0。
第二步:求和式
我们要计算: [ S = \sum_{y=0}^{\lfloor (n+1)/2 \rfloor} \binom{n-y+1}{y} \cdot (n-y)^a \cdot y^b ] 其中 ((n-y)^a y^b) 是特征值,(\binom{n-y+1}{y}) 是对应 (y) 的序列数量。
第三步:直接计算的可行性
(n) 可达 (10^7),但 (a,b \le 45),所以虽然 (n) 很大,但幂次不高。
直接枚举 (y) 从 0 到 (\lfloor (n+1)/2 \rfloor) 是不可能的((O(n)) 会超时,(n) 太大)。我们需要更快的算法。
第四步:递推思路
设 (F(n) = \sum_{y} \binom{n-y+1}{y} (n-y)^a y^b)。
组合数 (\binom{n-y+1}{y}) 满足递推关系:
令 (C(n,y) = \binom{n-y+1}{y}),则
(C(n,y) = C(n-1,y) + C(n-2, y-1))(可以验证,这是组合恒等式)。因此可以尝试对 (n) 建立递推,但这里附加了权重 ((n-y)^a y^b),导致直接递推困难。
第五步:生成函数法
考虑生成函数: [ G(t) = \sum_{y \ge 0} \binom{n-y+1}{y} t^y ] 已知无相邻 1 的 0-1 串的生成函数与 Fibonacci 多项式有关: [ \sum_{y} \binom{n-y+1}{y} z^y = F_{n+1}(z) \quad \text{某种形式} ] 更准确:(\sum_{y} \binom{n-y+1}{y} x^y) 是 Fibonacci 多项式的系数。
我们要求的是 (\sum_y \binom{n-y+1}{y} (n-y)^a y^b)。
注意到 ((n-y)^a = \sum_{k=0}^a \binom{a}{k} n^{a-k} (-y)^k),二项展开: [ (n-y)^a y^b = \sum_{k=0}^a \binom{a}{k} n^{a-k} (-1)^k y^{k+b} ] 所以原和式变为: [ S = \sum_{k=0}^a \binom{a}{k} n^{a-k} (-1)^k \left[ \sum_{y} \binom{n-y+1}{y} y^{k+b} \right] ]
第六步:问题转化为求 (\sum_y \binom{n-y+1}{y} y^m)
设 (T_m(n) = \sum_y \binom{n-y+1}{y} y^m)。
利用 (C(n,y)) 的递推: [ \binom{n-y+1}{y} = \binom{n-y}{y} + \binom{n-y}{y-1} ] 但更好用: [ \binom{n-y+1}{y} = \binom{n-y}{y} + \binom{n-y}{y-1} ] 和 [ \binom{n-y}{y} = \binom{n-1-y}{y} + \binom{n-2-(y-1)}{y-1} \quad \text{复杂} ]
不过已知标准结果: [ \sum_{y} \binom{n-y+1}{y} y^m ] 可以用 线性递推 计算,因为 (\binom{n-y+1}{y}) 本身是常系数线性递推(斐波那契类)的系数,乘上 (y^m) 后仍可化为高阶线性递推。
具体地:
序列 (A_n = \sum_{y} \binom{n-y+1}{y} y^m) 满足线性递推,递推阶数至多 (2(m+1))。
因为 (y^m) 可写成关于 (n) 和 (y) 的多项式,而组合数部分满足 Fibonacci 递推 (f_n = f_{n-1} + f_{n-2})(对于总个数),带权后仍在多项式递推类中。
第七步:利用矩阵快速幂
设 (dp[n][m] = \sum_{y} \binom{n-y+1}{y} y^m)。
我们可对每个 (m) 建立递推,但 (n) 很大((10^7)),递推阶数不高时可用矩阵快速幂 (O(\log n)),但 (m) 最大 (a+b \le 90),矩阵大小 (O(m)) 的话矩阵乘法的代价 (O(m^3 \log n)) 太大。需要更优方法。
第八步:多项式插值法
注意 (T_m(n) = \sum_{y} \binom{n-y+1}{y} y^m) 是关于 (n) 的多项式,次数为 (m+1)? 我们来验证阶数:
(\binom{n-y+1}{y}) 是 (n) 的 (y) 次多项式(看作多项式函数)。
(T_m(n)) 是这些多项式的和,乘以 (y^m),所以是 (n) 的 至多 (m+1) 次多项式(因为 (y) 最大约 (n/2),但多项式次数由项决定)。因此,对于固定的 (m),(T_m(n)) 是 (n) 的 (m+1) 次多项式。
那么我们可以:
- 对于每个 (m = 0, 1, \dots, a+b),计算 (T_m(0), T_m(1), \dots, T_m(m+1))(暴力算,因为 (m) 小)。
- 用拉格朗日插值得到多项式 (T_m(n)) 的系数(模 (m))。
- 然后代入需要的 (n)。
这样预计算 (O((a+b)^3)),然后每个查询 (O((a+b)^2)) 得到 (T_m(n)),再组合得到答案。
步骤:
- 枚举 (m = k+b),其中 (k=0..a)。
- 对每个 (m),计算 (T_m(j)) 对 (j=0..m+1): [ T_m(j) = \sum_{y=0}^{\lfloor (j+1)/2 \rfloor} \binom{j-y+1}{y} y^m ] 直接算,因为 (j \le m+1 \le 91),非常快。
- 用这些点值插值得到 (T_m(n) \bmod M)。
- 计算 [ S = \sum_{k=0}^a \binom{a}{k} n^{a-k} (-1)^k T_{k+b}(n) \bmod M ]
第九步:模质数运算
(M) 是质数(题目保证),所以可以用费马小定理求逆元,进行拉格朗日插值。
插值公式: [ T_m(n) = \sum_{i=0}^{d} T_m(i) \cdot \prod_{j \neq i} \frac{n-j}{i-j} \pmod{M} ] 其中 (d = m+1)。
第十步:时间复杂度
- 计算 (T_m(j)):(O((a+b)^3)) 因为 (m \le a+b \le 90),(j \le m+1),所以 (\le 91),每算一个 (T_m(j)) 需要 (O(j)) 求和,总 (O((a+b)^3)) 约 (90^3 = 729000),可接受。
- 插值:对每个 (m) 插值一次 (O(d^2)),总 (O((a+b)^3))。
- 最终求和:(O(a))。
因此整体可行。
样例验证
样例 1:(n=3, a=1, b=2)
(S = \sum_{k=0}^1 \binom{1}{k} 3^{1-k} (-1)^k T_{k+2}(3))
= ( \binom{1}{0}3^1 T_2(3) + \binom{1}{1}3^0 (-1) T_3(3) )
= (3 T_2(3) - T_3(3))。计算 (T_2(3)):
(y=0): (\binom{4}{0}0^2=0)
(y=1): (\binom{3}{1}1^2=3)
(y=2): (\binom{2}{2}4=4),和=7
(T_3(3)):
(y=0:0, y=1:\binom{3}{1}1^3=3, y=2:\binom{2}{2}8=8),和=11
则 (3\times7 - 11 = 21-11=10),匹配样例。
最终算法流程
- 读入 (n,a,b,M)。
- 令 (L = a+b)。
- 对 (m=0) 到 (L):
- 计算 (T_m(0..m+1)):
(T_m(j) = \sum_{y=0}^{\lfloor (j+1)/2 \rfloor} \binom{j-y+1}{y} y^m \bmod M)。 - 用点值 ((0..m+1, T_m)) 插值得到多项式,并计算 (T_m(n) \bmod M)。
- 计算 (T_m(0..m+1)):
- 计算答案: [ S = \sum_{k=0}^a \binom{a}{k} n^{a-k} (-1)^k T_{k+b}(n) \bmod M ]
- 输出 (S)。
这样就能在 (O((a+b)^3)) 时间内求解,适用于 (a,b \le 45) 的大 (n)。
- 1
信息
- ID
- 6110
- 时间
- 2000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 3
- 已通过
- 1
- 上传者