尽量简单易懂
题目
M斐波那契数列F[n]是一种整数数列,它的定义如下:
F[0] = a
F[1] = b
F[n] = F[n-1] * F[n-2] ( n > 1 )
现在给出a, b, n,你能求出F[n]的值吗?
输入
输入包含多组测试数据;
每组数据占一行,包含3个整数a, b, n( 0 <= a, b, n <= 10^9 )
输出
对每组测试数据请输出一个整数F[n],由于F[n]可能很大,你只需输出F[n]对1000000007取模后的值即可,每组数据输出一行。
样例输入
0 1 0 6 10 2
样例输出
0 60
题目链接:M斐波那契数列
思路
-
1. 首先易知(使M(-1)=1,下式即可完全满足题意)
f(n)=a^ *b ^
% mod =(a ^
% mod)*(b ^
% mod) %mod 其中M(n)为 斐波那契数列 n 0 1 2 3 4 5 6 7 M(n) 0 1 1 2 3 5 8 13
-
2. 求斐波那契数列
欧拉降幂公式如下
因为mod=1e9+7为素数,a<1e9,满足欧拉降幂公式
则 a ^ % mod = a ^
%mod
求n <10 ^ 9的斐波那契数列只能用矩阵快速幂(大又快,就是模板麻烦),而且要 %phi(mod)
代码
#include <iostream>
#include <algorithm>
#include <memory.h>
#include <cstdio>
using namespace std;
#define ll long long
int Euler(int n) //求欧拉函数
{
int res=n;
for(ll i=2;i*i<=n;++i){
if(n%i==0){
res=res/i*(i-1);
while(n%i==0)
n/=i;
}
}
if(n>1)
res-=res/n;
return res;
}
const ll mod=1e9+7;
const ll MOD=Euler(mod); //求mod的欧拉函数值
ll a,b,k;
const int N=4; //以下为矩阵快速幂,供Prons函数使用
ll tmp[N][N];
void mul(ll a[][N],ll b[][N],ll n)
{
memset(tmp,0,sizeof(tmp));
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
for(int k=0;k<n;k++)
tmp[i][j]=(tmp[i][j]+a[i][k]*b[k][j])%MOD; //这里余数是MOD
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
a[i][j]=tmp[i][j];
}
ll res[N][N];
void Pow(ll a[][N],ll k)
{
memset(res,0,sizeof(res));
for(int i=0;i<N;i++)
res[i][i]=1;
while(k){
if(k&1)
mul(res,a,N);
mul(a,a,N);
k>>=1;
}
}
ll Fib(ll n) //求斐波那契数列
{
if(n==-1) return 1; // k==0时
ll vis[N][N]={{1,1},{1,0}};
Pow(vis,n);
return res[0][1];
}
ll qpow(ll a,ll b) //快速幂,最后使用
{
ll ans=1;
while(b)
{
if(b&1)
ans=ans*a%mod;
a=a*a%mod;
b>>=1;
}
return ans;
}
int main()
{
while(~scanf("%lld%lld%lld",&a,&b,&k))
{
ll ans1=qpow(a,Fib(k-1));
ll ans2=qpow(b,Fib(k));
cout<<ans1*ans2%mod<<endl;
}
return 0;
}