Problem Description M斐波那契数列F[n]是一种整数数列,它的定义如下:
F[0] = a
F[1] = b
F[n] = F[n-1] * F[n-2] ( n > 1 )
现在给出a, b, n,你能求出F[n]的值吗?
Input 输入包含多组测试数据;
每组数据占一行,包含3个整数a, b, n( 0 <= a, b, n <= 10^9 )
Output 对每组测试数据请输出一个整数F[n],由于F[n]可能很大,你只需输出F[n]对1000000007取模后的值即可,每组数据输出一行。
Sample Input
0 1 0 6 10 2
Sample Output
0 60
Source 2013金山西山居创意游戏程序挑战赛——初赛(2)
思路:
1. 首先得出封闭形式:
F[n]=a (n=0)
F[n]=a^Fib[n-1]*b^Fib[n] (n>0)
2. 发现1000000007是质数,遂用费马小定理,得
F[n]%m=a^(Fib[n-1]%(m-1))*b^(Fib[n]%(m-1))%m
3. f[n]%(m-1)的计算用矩阵快速幂
4. a^x的计算用快速幂
完整代码:
/*0ms,232KB*/ #includeconst long long M = 1000000007; struct Matrix { long long mat[2][2]; }; const Matrix P = { 1, 1, 1, 0, }; const Matrix I = { 1, 0, 0, 1, }; Matrix matrixmul(Matrix a, Matrix b) { Matrix c; int i, j, k; for (i = 0 ; i < 2; ++i) for (j = 0; j < 2; ++j) { c.mat[i][j] = 0; for (k = 0; k < 2; ++k) ///利用费马小定理 c.mat[i][j] += a.mat[i][k] * b.mat[k][j] % (M - 1);///行*列 c.mat[i][j] %= (M - 1); } return c; } ///P^n%(M-1),P已在程序开头定义 Matrix quickpow(long long n) { Matrix m = P, ret = I; while (n) { if (n & 1) ret = matrixmul(ret, m); n >>= 1; m = matrixmul(m, m); } return ret; } ///a^b%M long long quickpow(long long a, long long b) { long long ret = 1; while (b) { if (b & 1) ret = ret * a % M; b >>= 1; a = a * a % M; } return ret; } int main() { long long a, b, n; Matrix q; while (~scanf(%I64d%I64d%I64d, &a, &b, &n)) { q = quickpow(n);///不需要特判哦 printf(%I64d , quickpow(a, q.mat[1][1]) * quickpow(b, q.mat[1][0]) % M);///a^Fib(n-1)*b^Fib(n)%M } return 0; }