HDU 4549 M斐波那契数列
题目链接:HDU 4549 M斐波那契数列
题目大意:
题解:
先找规律:
\(F_0=a,\)
\(F_1=b,\)
\(F_2=a\times b,\)
\(F_3=a\times b^2,\)
\(F_4=a^2\times b^3,\)
\(F_5=a^3\times b^5,\)
\(...\)
\(F_n=a^{f_{n-1}}\times b^{f_n}\)(\(f_n\)为斐波那契数列)
所以题目就变成了用矩阵快速幂求斐波那契数列。
构造矩阵:
\[\left(\begin{matrix}
f_i \\
f_{i-1}
\end{matrix}\right)
=
\left(\begin{matrix}
1 & 1 \\
1 & 0
\end{matrix}\right)
\times
\left(\begin{matrix}
f_{i-1} \\
f_{i-2}
\end{matrix}\right)
\]
所以:
\[\left(\begin{matrix}
f_n \\
f_{n-1}
\end{matrix}\right)
=
\left(\begin{matrix}
1 & 1 \\
1 & 0
\end{matrix}\right)^{n-1}
\times
\left(\begin{matrix}
1 \\
0
\end{matrix}\right)
\]
因为结果需要对\(1e9+7\)取余,由费马小定理可知\(a^{p-1}\equiv 1(\mod p)\),
由此可得:
\[\begin{aligned}
ans&=(a^{f_{n-1}}\%mod\times b^{f_n}\%mod)\%mod \\
&=((a^{f_{n-1}\%(mod-1)}\times a^{(mod-1)^{[f_{n-1}\div (mod-1)]}})\%mod+(b^{f_n\%(mod-1)}\times b^{(mod-1)^{[f_n\div (mod-1)]}})\%mod)\%mod \\
&=(a^{f_{n-1}\%(mod-1)}\%mod+b^{f_n\%(mod-1)}\%mod)\%mod
\end{aligned}
\]
所以在矩阵快速幂中对\(1e9+6\)取余,在快速幂中对\(1e9+7\)取余。
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
#define ll long long
const int mod = 1e9 + 7;
struct Matrix { // 矩阵
int row, col;
ll num[2][2];
};
Matrix multiply(Matrix a, Matrix b) { // 矩阵乘法
Matrix temp;
temp.row = a.row, temp.col = b.col;
memset(temp.num, 0, sizeof(temp.num));
for (int i = 0; i < a.row; ++i)
for (int j = 0; j < b.col; ++j)
for (int k = 0; k < a.col; ++k)
temp.num[i][j] = (temp.num[i][j] + a.num[i][k] * b.num[k][j]) % (mod - 1);
return temp;
}
Matrix MatrixFastPow(Matrix base, ll k) { // 矩阵快速幂
Matrix ans;
ans.row = ans.col = 2;
ans.num[0][0] = ans.num[1][1] = 1;
ans.num[0][1] = ans.num[1][0] = 0;
while (k) {
if (k & 1) ans = multiply(ans, base);
base = multiply(base, base);
k >>= 1;
}
return ans;
}
ll fastPow(ll n, ll k) { // 快速幂
ll ans = 1;
while (k) {
if (k & 1) ans = ans * n % mod;
n = n * n % mod;
k >>= 1;
}
return ans;
}
int main() {
ll a, b, n;
Matrix base;
base.row = base.col = 2;
base.num[0][0] = base.num[0][1] = base.num[1][0] = 1;
base.num[1][1] = 0;
while (~scanf("%lld%lld%lld", &a, &b, &n)) {
if (!n) {
printf("%lld\n", a);
} else {
Matrix ans = MatrixFastPow(base, n - 1);
printf("%lld\n", fastPow(a, ans.num[1][0]) * fastPow(b, ans.num[0][0]) % mod);
}
}
return 0;
}