HDU4549 M斐波那契数
M斐波那契数列
题目分析:
M斐波那契数列F[n]是一种整数数列,它的定义例如以下:
F[0] = a
F[1] = b
F[n] = F[n-1] * F[n-2] ( n > 1 )
如今给出a, b, n,你能求出F[n]的值吗?
算法分析:
经过前面几项的推导,你会发现当中a,b的个数为斐波那契数同样。而我们知道斐波那契数是到20项后就会非常大,所以要处理。而我们依据欧拉定理(费马小定理)可知道
A^(P-1)同余 1 模C,这题的C是质数,并且A,C是互质的。
所以直接A^(B%(C-1)) %C = A^B % C
比較一般的结论是 A^B %C = A^( B%phi(C)+phi(C) ) %C B>=phi(C)
#include <iostream> #include <algorithm> #include <cstdio> #include <cstring> using namespace std; typedef long long LL; const int MOD = 1000000007; struct Matrix{ LL mat[2][2]; LL row,col; Matrix(){}; Matrix(LL _r,LL _c):row(_r),col(_c){}; }; Matrix I(2,2),P(2,2); void Init(){ P.mat[0][0] = 0; P.mat[0][1] = P.mat[1][0] = P.mat[1][1] = 1; I.mat[0][0] = I.mat[1][1] = 1; I.mat[0][1] = I.mat[1][0] = 0; } //矩阵相乘 Matrix mul(Matrix A,Matrix B,LL mod){ Matrix C(2,2); memset(C.mat,0,sizeof(C.mat)); for(int i = 0;i < A.row;++i){ for(int k = 0;k < B.row;++k){ for(int j = 0;j < B.col;++j){ C.mat[i][j] = (C.mat[i][j] + A.mat[i][k] * B.mat[k][j] % mod) % mod; } } } return C; } //fib[n] % (c - 1) Matrix powmod(Matrix A,LL n,LL mod){ Matrix B = I; while(n > 0){ if(n & 1) B = mul(B,A,mod); A = mul(A,A,mod); n >>= 1; } return B; } //a ^ b % c LL powmod(LL a,LL n,LL mod){ LL res = 1; while(n > 0){ if(n & 1) res = (res * a) % mod; a = a * a % mod; n >>= 1; } return res; } int main() { Init(); LL a,b,n; while(~scanf("%I64d%I64d%I64d",&a,&b,&n)){ Matrix A = powmod(P,n,MOD - 1); //fib[n] % (mod -1 ) printf("%I64d\n",powmod(a,A.mat[0][0],MOD) * powmod(b,A.mat[1][0],MOD) % MOD); } return 0; }