矩阵快速幂优化递推
广义斐波那契数列
题目描述
广义的斐波那契数列是指形如 \(a_n=p\times a_{n-1}+q\times a_{n-2}\) 的数列。
今给定数列的两系数 \(p\) 和 \(q\),以及数列的最前两项 \(a_1\) 和 $ a_2$,另给出两个整数 \(n\) 和 \(m\),试求数列的第 \(n\) 项 \(a_n\) 对 \(m\) 取模后的结果。
输入格式
输入包含一行六个整数,\(p,q,a_1,a_2,n,m\)。
输出格式
输出包含一行一个整数表示答案。
样例 #1
样例输入 #1
1 1 1 1 10 7
样例输出 #1
6
提示
数列第 $10 $项是 \(55\),\(55 \bmod 7 = 6\)。
【数据范围】
对于 \(100\%\) 的数据,\(p,q,a_1,a_2 \in [0,2^{31}-1]\),\(1\le n,m \le 2^{31}-1\)。
#include <bits/stdc++.h>
using namespace std;
int p, q, a1, a2, n, mo;
struct matrix {
int n, m;
int z[3][3];
matrix() {
memset(z, 0, sizeof z);
}
} _, A;
matrix operator*(const matrix &x, const matrix &y) {
matrix z;
z.n = x.n;
z.m = y.m;
for (int i = 1; i <= z.n; i++)
for (int k = 1; k <= x.m; k++)
for (int j = 1; j <= z.m; j++)
z.z[i][j] = (z.z[i][j] + 1ll * x.z[i][k] * y.z[k][j] % mo) % mo;
return z;
}
int main() {
scanf("%d%d%d%d%d%d", &p, &q, &a1, &a2, &n, &mo);
p %= mo, q %= mo;
if (n == 1)printf("%d", a1 % mo), exit(0);
if (n == 2)printf("%d", a2 % mo), exit(0);
_.n = 2;
_.m = 1;
_.z[1][1] = a2;
_.z[2][1] = a1;
A.n = 2, A.m = 2;
A.z[1][1] = p, A.z[1][2] = q;
A.z[2][1] = 1, A.z[2][2] = 0;
int mi = n-2;
for (; mi; mi >>= 1, A = A * A)
if (mi & 1)_ = A * _;//左乘:注意A和_位置不能换
printf("%d", _.z[1][1]);
return 0;
}

浙公网安备 33010602011771号