#jZCybttg060504. 1644:【例 4】佳佳的 Fibonacci
1644:【例 4】佳佳的 Fibonacci
1644:【例 4】佳佳的 Fibonacci
题目描述
佳佳对数学,尤其对数列十分感兴趣。在研究完 Fibonacci 数列后,他创造出许多稀奇古怪的数列。例如用 表示 Fibonacci 前 项和 的值,即 ,其中 。可这对佳佳来说还是小菜一碟。
终于,她找到了一个自己解决不了的问题。用 表示 Fibonacci 数列前 项变形后的和 的值。
现在佳佳告诉你了一个 和 ,请求出 的值。
输入格式
输入数据包括一行,两个用空格隔开的整数 。
输出格式
仅一行, 的值。
样例
样例输入 #1
5 5
样例输出 #1
1
样例解释 #1
- Fibonacci 数列前 项:。
- $T(5) = 1 \times 1 + 2 \times 1 + 3 \times 2 + 4 \times 3 + 5 \times 5 = 1 + 2 + 6 + 12 + 25 = 46$。
- 。
数据范围
- 对于 的数据,;
- 对于 的数据,;
- 对于 的数据,。
时空限制
- 时间限制:1000 ms
- 内存限制:524288 KB
注意: 很大,需要矩阵快速幂加速。我们需要计算 。
设 ,。
考虑递推关系:
我们希望将 表示为 等的线性组合。但 本身在变化,所以需要将 也纳入状态向量。
定义状态向量:
$$\mathbf{X}_n = \begin{bmatrix} F_n \\ F_{n-1} \\ S_n \\ T_n \\ n \\ 1 \end{bmatrix}$$注意: 是必要的,因为递推需要前两项。 和 是为了构造 。
我们希望找到转移矩阵 ,使得 。
写出 各分量:
- $F_{n+1} = 1 \cdot F_n + 1 \cdot F_{n-1} + 0 \cdot S_n + 0 \cdot T_n + 0 \cdot n + 0 \cdot 1$
- $F_n = 1 \cdot F_n + 0 \cdot F_{n-1} + 0 \cdot S_n + 0 \cdot T_n + 0 \cdot n + 0 \cdot 1$
- $S_{n+1} = S_n + F_{n+1} = 0 \cdot F_n + 0 \cdot F_{n-1} + 1 \cdot S_n + 0 \cdot T_n + 0 \cdot n + 0 \cdot 1 + F_{n+1}$,而 已由第一行表示,所以 $S_{n+1} = 1 \cdot F_n + 1 \cdot F_{n-1} + 1 \cdot S_n + 0 \cdot T_n + 0 \cdot n + 0 \cdot 1$
- $T_{n+1} = T_n + (n+1) F_{n+1} = T_n + n F_{n+1} + F_{n+1}$。将 用第一行表示, 用第五行表示, 用第六行表示。所以:
- $T_{n+1} = 0 \cdot F_n + 0 \cdot F_{n-1} + 0 \cdot S_n + 1 \cdot T_n + 0 \cdot n + 0 \cdot 1 + n F_{n+1} + F_{n+1}$
- 而 ,所以 ,其中 是第五个分量。
- 因此, 的表达式包含 的线性组合,但 乘以 和 不是线性组合(因为 本身是变量)。实际上,我们需要将 视为整体?但状态向量中没有 ,所以不能直接线性表示。因此,我们需要增加状态分量,或者换一种思路。
另一种常见方法:注意到 $T(n) = \sum_{i=1}^n i F_i = n S_n - \sum_{i=1}^{n-1} S_i$。因为 $\sum_{i=1}^{n-1} S_i = \sum_{i=1}^{n-1} \sum_{j=1}^i F_j = \sum_{j=1}^{n-1} (n-j) F_j = n \sum_{j=1}^{n-1} F_j - \sum_{j=1}^{n-1} j F_j = n (S_n - F_n) - (T_n - n F_n) = n S_n - n F_n - T_n + n F_n = n S_n - T_n$。整理得:
所以
这个公式似乎没有简化问题。
更直接的方法:构造 矩阵,包含 之类的状态。但这样会复杂。
实际上,我们可以定义状态向量为:
$$\mathbf{Y}_n = \begin{bmatrix} F_n \\ F_{n-1} \\ n F_n \\ (n-1) F_{n-1} \\ 1 \end{bmatrix}$$但递推时 会变化。
另一种思路:考虑 的递推:
而 有递推关系。所以我们需要同时维护 。但 每次加 ,可以表示为 ,所以 可以线性表示。
定义状态向量:
$$\mathbf{Z}_n = \begin{bmatrix} F_n \\ F_{n-1} \\ T_n \\ n \\ 1 \end{bmatrix}$$则 为:
- $T_{n+1} = T_n + (n+1) F_{n+1} = T_n + (n+1)(F_n + F_{n-1}) = T_n + n F_n + n F_{n-1} + F_n + F_{n-1}$
因此,转移矩阵 满足 ,其中:
$$A = \begin{bmatrix} 1 & 1 & 0 & 0 & 0 \\ 1 & 0 & 0 & 0 & 0 \\ 1 & 1 & 1 & 1 & 0 \\ 0 & 0 & 0 & 1 & 1 \\ 0 & 0 & 0 & 0 & 1 \end{bmatrix}$$解释:
- 第一行:$F_{n+1} = 1 \cdot F_n + 1 \cdot F_{n-1} + 0 \cdot T_n + 0 \cdot n + 0 \cdot 1$
- 第二行:$F_n = 1 \cdot F_n + 0 \cdot F_{n-1} + 0 \cdot T_n + 0 \cdot n + 0 \cdot 1$
- 第三行:$T_{n+1} = 1 \cdot F_n + 1 \cdot F_{n-1} + 1 \cdot T_n + 1 \cdot n + 0 \cdot 1$(注意还需要 中的 和 系数已包含,但 和 中的 来自第四列,所以第三行第四列系数为 表示 的贡献?实际上,$T_{n+1} = T_n + (n+1)(F_n + F_{n-1}) = T_n + n F_n + n F_{n-1} + F_n + F_{n-1}$。所以 系数为 (来自 )和 的系数为 (来自 )?但矩阵乘法是线性组合,不能有 这样的项,因为 和 是分开的分量。所以我们需要将 拆开?实际上,在状态向量中, 和 是独立分量,乘积 不是分量的线性组合。因此,这个矩阵不能正确表示 。
所以我们需要将 也作为状态分量。定义状态向量:
$$\mathbf{W}_n = \begin{bmatrix} F_n \\ F_{n-1} \\ n F_n \\ (n-1) F_{n-1} \\ T_n \\ 1 \end{bmatrix}$$这样,每个分量都是线性的。递推关系:
- $(n+1) F_{n+1} = (n+1)(F_n + F_{n-1}) = n F_n + n F_{n-1} + F_n + F_{n-1}$
- (保持不变?实际上, 成为新的第三分量,原来的第三分量 在下一状态中变为 的一部分,但我们需要递推关系)
这样,我们可以写出转移矩阵 。但状态向量有 个分量,矩阵为 。
具体地,令 ,其中 ,。则 为:
- $U_{n+1} = (n+1) F_{n+1} = (n+1)(F_n + F_{n-1}) = n F_n + n F_{n-1} + F_n + F_{n-1} = U_n + (V_n + F_{n-1}) + F_n + F_{n-1}$,因为 ,所以 。所以 。
- (因为 )
因此,转移矩阵 为:
$$A = \begin{bmatrix} 1 & 1 & 0 & 0 & 0 & 0 \\ 1 & 0 & 0 & 0 & 0 & 0 \\ 1 & 2 & 1 & 1 & 0 & 0 \\ 1 & 0 & 1 & 0 & 0 & 0 \\ 1 & 2 & 1 & 1 & 1 & 0 \\ 0 & 0 & 0 & 0 & 0 & 1 \end{bmatrix}$$验证:
- 第一行:$F_{n+1} = 1 F_n + 1 F_{n-1} + 0 U_n + 0 V_n + 0 T_n + 0$
- 第二行:$F_n = 1 F_n + 0 F_{n-1} + 0 U_n + 0 V_n + 0 T_n + 0$
- 第三行:$U_{n+1} = 1 F_n + 2 F_{n-1} + 1 U_n + 1 V_n + 0 T_n + 0$
- 第四行:$V_{n+1} = 1 F_n + 0 F_{n-1} + 1 U_n + 0 V_n + 0 T_n + 0$
- 第五行:$T_{n+1} = 1 F_n + 2 F_{n-1} + 1 U_n + 1 V_n + 1 T_n + 0$
- 第六行:
初始状态:,。但 Fibonacci 数列通常定义 。这里 。,,。所以 。
那么 , 是第五个分量。
因此,算法步骤:
- 构造 矩阵 和初始向量 。
- 计算 (矩阵快速幂)。
- 计算 。
- 输出 的第五个元素(即 )模 。
注意 可能为 ,此时 , 是单位矩阵, 的第五个分量为 ,正确。
由于 可达 ,矩阵快速幂需要 ,可以接受。注意取模 , 也可能很大,但矩阵元素在计算过程中取模即可。