Files
HuangHai 1f397eca87 'commit'
2025-08-30 18:35:01 +08:00

137 lines
3.0 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

##[$AcWing$ $1303$. 斐波那契前 $n$ 项和](https://www.acwing.com/problem/content/1305/)
### 一、题目描述
大家都知道 $Fibonacci$ 数列吧,$f_1=1,f_2=1,f_3=2,f_4=3,…,f_n=f_{n−1}+f_{n−2}$。
现在问题很简单,输入 $n$ 和 $m$,求 $f_n$ 的前 $n$ 项和 $S_n \ mod \ m$。
**输入格式**
共一行,包含两个整数 $n$ 和 $m$。
**输出格式**
输出前 $n$ 项和 $S_n\ mod\ m$ 的值。
**数据范围**
$1≤n≤2000000000,1≤m≤1000000010$
**输入样例**:
$5$ $1000$
**输出样例**:
$12$
### 二、解题思路
普通的迭代法,是线性的,$n$的上限是$2e9$,循环的话会超时,需要想其它办法。
**矩阵快速幂**
$$\large \begin{bmatrix} s_n & f_{n+1}& f_n \end{bmatrix} \times
\begin{bmatrix}
a&b &c \\
d&e & f \\
h&i & j \\
\end{bmatrix} = \begin{bmatrix} s_{n+1} & f_{n+2}& f_{n+1} \end{bmatrix}$$
$\therefore \\
s_{n+1}= s_n \times a+f_{n+1} \times d+f_n \times h \\
f_{n+2}= s_n \times b + f_{n+1} \times e + f_n \times i \\
f_{n+1}= s_n \times c + f_{n+1} \times f + f_n \times j
$
根据题目的现实含义:
$s_{n+1}=s_n+f_{n+1}$
$f_{n+2}=f_n+f_{n+1}$
推导出:
$a=1,d=1,h=0$
$b=0,e=1,i=1$
$c=0,f=1,j=0$
整理出矩阵就是:
$m=\begin{bmatrix}
1 & 0 & 0 \\
1 & 1 & 1 \\
0 & 1 & 0
\end{bmatrix}$
已知 $s_1=1,f_2=1,f_1=1$,使用矩阵快速幂可以求解 $s_n$。
即$b=\begin{bmatrix}
1 & 1& 1
\end{bmatrix}$
$\begin{bmatrix}s_1 & f_2 & f_1 \end{bmatrix} \times
\begin{bmatrix}
1 & 0 & 0 \\
1 & 1 & 1 \\
0 & 1 & 0
\end{bmatrix} =\begin{bmatrix}s_2 & f_3 & f_2 \end{bmatrix}
$ ①
$\begin{bmatrix}s_2 & f_3 & f_2 \end{bmatrix} \times
\begin{bmatrix}
1 & 0 & 0 \\
1 & 1 & 1 \\
0 & 1 & 0
\end{bmatrix} =\begin{bmatrix}s_3 & f_4 & f_3 \end{bmatrix}
$ ②
将 ① 代入 ② 得到:
$\begin{bmatrix}s_1 & f_2 & f_1 \end{bmatrix} \times
\begin{bmatrix}
1 & 0 & 0 \\
1 & 1 & 1 \\
0 & 1 & 0
\end{bmatrix}^2 =\begin{bmatrix}s_3 & f_4 & f_3 \end{bmatrix}
$
通过数学归纳法,得:
$\begin{bmatrix}s_1 & f_2 & f_1 \end{bmatrix} \times
\begin{bmatrix}
1 & 0 & 0 \\
1 & 1 & 1 \\
0 & 1 & 0
\end{bmatrix}^{n-1} =\begin{bmatrix}s_n & f_{n+1} & f_n \end{bmatrix}
$
### 三、实现代码
```cpp {.line-numbers}
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl "\n"
const int N = 3;
int n, mod;
// 矩阵乘法
void mul(int a[][N], int b[][N], int c[][N]) {
int t[N][N] = {0};
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++)
for (int k = 0; k < N; k++)
t[i][j] = (t[i][j] + (a[i][k] * b[k][j]) % mod) % mod;
}
memcpy(c, t, sizeof t);
}
signed main() {
int b[N][N] = {1, 1, 1};
int m[N][N] = {
{1, 0, 0},
{1, 1, 1},
{0, 1, 0}};
cin >> n >> mod;
for (int i = n - 1; i; i >>= 1) {
if (i & 1) mul(b, m, b);
mul(m, m, m);
}
printf("%d\n", b[0][0]);
}
```