题目
(f_0=a)
(f_1=b)
(f_i=f_{i-1} imes f_{i-2},i>1)
求 (f_n)。
思路
(f_0=a,f_1=b,f_2=ab,f_3=ab^2,f_4=a^2b^3,f_5=a^3b^5)。
发现指数都是斐波那契数列中相邻的两个数,指数可以用矩阵快速幂加速递推去求。
因为模数为 (1e9+7) 是个质数,可以用费马小定理降幂。
Code
#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
const int mod = 1000000007;
int a, b, n;
struct Matrix {
int g[3][3];
Matrix() { memset(g, 0, sizeof g); }
void one() { g[1][1] = g[2][2] = 1; }
friend Matrix operator * (Matrix m1, Matrix m2) {
Matrix ans;
for (int k = 1; k <= 2; ++k) {
for (int i = 1; i <= 2; ++i) {
for (int j = 1; j <= 2; ++j) {
ans.g[i][j] = (ans.g[i][j] + (1ll * m1.g[i][k] * m2.g[k][j] % (mod - 1))) % (mod - 1);
}
}
}
return ans;
}
}tra, res, f;
Matrix qpow(Matrix a, int b) {
Matrix ans, base = a;
ans.one();
while (b) {
if (b & 1) ans = ans * base;
base = base * base;
b >>= 1;
}
return ans;
}
int qp(int a, int b) {
int ans = 1, base = a;
while (b) {
if (b & 1) ans = 1ll * ans * base % mod;
base = 1ll * base * base % mod;
b >>= 1;
}
return ans;
}
int main() {
while (scanf("%d %d %d", &a, &b, &n) != EOF) {
if (n == 0) {
printf("%d
", a);
continue;
}
tra.g[1][1] = tra.g[1][2] = tra.g[2][1] = 1, tra.g[2][2] = 0;
f.g[1][1] = 1, f.g[2][1] = res.g[1][1] = res.g[2][1] = 0;
tra = qpow(tra, n - 1);
for (int k = 1; k <= 2; ++k) {
for (int i = 1; i <= 2; ++i) {
for (int j = 1; j <= 1; ++j) {
res.g[i][j] = (res.g[i][j] + (1ll * tra.g[i][k] * f.g[k][j] % (mod - 1))) % (mod - 1);
}
}
}
printf("%lld
", (1ll * qp(a, res.g[2][1]) * qp(b, res.g[1][1])) % mod);
}
return 0;
}