145 lines
3.2 KiB
Markdown
145 lines
3.2 KiB
Markdown
|
|
##[$AcWing$ $1304$. 佳佳的斐波那契](https://www.acwing.com/problem/content/1306/)
|
|||
|
|
### 一、题目描述
|
|||
|
|
佳佳对数学,尤其对数列十分感兴趣。
|
|||
|
|
|
|||
|
|
在研究完 $Fibonacci$ 数列后,她创造出许多稀奇古怪的数列。
|
|||
|
|
|
|||
|
|
例如用 $S(n)$ 表示 $Fibonacci$ 前 $n$ 项和 $mod\ m$ 的值,即 $S(n)=(F_1+F_2+…+F_n)\ mod\ m$,其中 $F_1=F_2=1,F_i=F_{i−1}+F_{i−2}$。
|
|||
|
|
|
|||
|
|
可这对佳佳来说还是小菜一碟。
|
|||
|
|
|
|||
|
|
终于,她找到了一个自己解决不了的问题。
|
|||
|
|
|
|||
|
|
用 $T(n)=(F_1+2F_2+3F_3+…+nF_n)\ mod\ m$ 表示 $Fibonacci$ 数列前 $n$ 项变形后的和 $mod\ m$ 的值。
|
|||
|
|
|
|||
|
|
现在佳佳告诉你了一个 $n$ 和 $m$,请求出 $T(n)$ 的值。
|
|||
|
|
|
|||
|
|
**输入格式**
|
|||
|
|
共一行,包含两个整数 $n$ 和 $m$。
|
|||
|
|
|
|||
|
|
**输出格式**
|
|||
|
|
共一行,输出 $T(n)$ 的值。
|
|||
|
|
|
|||
|
|
**数据范围**
|
|||
|
|
$1≤n,m≤2^{31}−1$
|
|||
|
|
|
|||
|
|
**输入样例**:
|
|||
|
|
$5$ $5$
|
|||
|
|
|
|||
|
|
**输出样例**:
|
|||
|
|
$1$
|
|||
|
|
|
|||
|
|
**样例解释**
|
|||
|
|
$T(5)=(1+2×1+3×2+4×3+5×5)\ mod\ 5=1$
|
|||
|
|
|
|||
|
|
### 二、推导过程
|
|||
|
|
$$\because S_n=F_1+F_2+⋯+F_n=\sum_{i=1}^{n}F_i \\
|
|||
|
|
T_n=F_1+2*F_2+...+nF_n=\sum_{i=1}^{n}iF_i$$
|
|||
|
|
|
|||
|
|
我们需要利用$T_n$构造新的数列,从而消去变量$i$,最后再反解出$T_n$:
|
|||
|
|
|
|||
|
|
$$\therefore nS_n-T_n=(n-1)F_1+(n-2)F_2+...+F_{n-1}$$
|
|||
|
|
令$C_n=nS_n-T_n$
|
|||
|
|
|
|||
|
|
$$\therefore C_n=(n-1)F_1+(n-2)F_2+...+F_{n-1} \ ①$$
|
|||
|
|
$$C_{n+1}=nF_1+(n-1)F_2+...+F_{n} \ ② $$
|
|||
|
|
|
|||
|
|
② 式 - ① 式
|
|||
|
|
|
|||
|
|
$$C_{n+1}-C_n=F_1+F_2+F_3+...+F_n=S_n$$
|
|||
|
|
|
|||
|
|
于是我们只需维护如下矩阵即可
|
|||
|
|
$$
|
|||
|
|
\begin{pmatrix}
|
|||
|
|
f_{n+1} & f_n & s_n & c_n
|
|||
|
|
\end{pmatrix}
|
|||
|
|
$$
|
|||
|
|
|
|||
|
|
有如下等式:
|
|||
|
|
$$
|
|||
|
|
\begin{pmatrix}
|
|||
|
|
f_{n+1} & f_n & s_n & c_n
|
|||
|
|
\end{pmatrix} \times
|
|||
|
|
\begin{pmatrix}
|
|||
|
|
1 & 1 & 1 & 0 \\
|
|||
|
|
1 & 0 & 0 & 0 \\
|
|||
|
|
0 & 0 & 1 & 1 \\
|
|||
|
|
0 & 0 & 0 & 1
|
|||
|
|
\end{pmatrix}=
|
|||
|
|
\begin{pmatrix}
|
|||
|
|
f_{n+2} & f_{n+1} & s_{n+1} & c_{n+1}
|
|||
|
|
\end{pmatrix}
|
|||
|
|
$$
|
|||
|
|
|
|||
|
|
然后直接使用矩阵快速幂便可以求解
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
**初始矩阵**
|
|||
|
|
$$\begin{pmatrix}
|
|||
|
|
f_{2} & f_{1} & s_{1} & c_{1} \\
|
|||
|
|
\end{pmatrix} =
|
|||
|
|
\begin{pmatrix}
|
|||
|
|
1 & 1 & 1 & 0
|
|||
|
|
\end{pmatrix}
|
|||
|
|
$$
|
|||
|
|
|
|||
|
|
**递推式**
|
|||
|
|
$$\begin{pmatrix}
|
|||
|
|
f_{n+1} & f_{n} & s_{n} & c_{n} \\
|
|||
|
|
\end{pmatrix} =\begin{pmatrix}
|
|||
|
|
f_{2} & f_{1} & s_{1} & c_{1} \\
|
|||
|
|
\end{pmatrix} \times
|
|||
|
|
\begin{pmatrix}
|
|||
|
|
1 & 1 & 1 & 0 \\
|
|||
|
|
1 & 0 & 0 & 0 \\
|
|||
|
|
0 & 0 & 1 & 1 \\
|
|||
|
|
0 & 0 & 0 & 1
|
|||
|
|
\end{pmatrix}^{n-1}
|
|||
|
|
$$
|
|||
|
|
|
|||
|
|
**答案**
|
|||
|
|
$T_n=nS_n-C_n =n\times b[0][2]-b[0][3]$
|
|||
|
|
|
|||
|
|
### $Code$
|
|||
|
|
```cpp {.line-numbers}
|
|||
|
|
#include <bits/stdc++.h>
|
|||
|
|
using namespace std;
|
|||
|
|
#define int long long
|
|||
|
|
#define endl "\n"
|
|||
|
|
|
|||
|
|
const int N = 4;
|
|||
|
|
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);
|
|||
|
|
}
|
|||
|
|
int main() {
|
|||
|
|
int b[N][N] = {1, 1, 1, 0};
|
|||
|
|
int m[N][N] = {
|
|||
|
|
{1, 1, 1, 0},
|
|||
|
|
{1, 0, 0, 0},
|
|||
|
|
{0, 0, 1, 1},
|
|||
|
|
{0, 0, 0, 1}};
|
|||
|
|
|
|||
|
|
cin >> n >> mod;
|
|||
|
|
for (int i = n - 1; i; i >>= 1) {
|
|||
|
|
if (i & 1) mul(b, m, b);
|
|||
|
|
mul(m, m, m);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int t = (n * b[0][2]) - b[0][3];
|
|||
|
|
t = (t % mod + mod) % mod;
|
|||
|
|
printf("%lld\n", t);
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
```
|