您的位置:首页 > 其它

HDU 4549 M斐波那契数列(矩阵快速幂+费马小定理)

2017-07-10 16:06 399 查看

M斐波那契数列

Time Limit : 3000/1000ms (Java/Other) Memory Limit : 65535/32768K (Java/Other)
Total Submission(s) : 43 Accepted Submission(s) : 28

Font: Times New Roman | Verdana | Georgia

Font Size: ← →

Problem Description

M斐波那契数列F
是一种整数数列,它的定义如下:

F[0] = a
F[1] = b
F
= F[n-1] * F[n-2] ( n > 1 )

现在给出a, b, n,你能求出F
的值吗?

Input

输入包含多组测试数据;
每组数据占一行,包含3个整数a, b, n( 0 <= a, b, n <= 10^9 )

Output

对每组测试数据请输出一个整数F
,由于F
可能很大,你只需输出F
对1000000007取模后的值即可,每组数据输出一行。

Sample Input

0 1 0
6 10 2


Sample Output

0
60


Source

2013金山西山居创意游戏程序挑战赛——初赛(2)
题解:

题目中 f
=a ^? * b^? ,a,b的指数,刚好可以使用斐波那契数列求解,
矩阵快速幂求斐波那契数列

费马小定理:
若p是质数,且gcd(a,p)=1,则 a ^ (p-1) = 1 (mod p)

#include <iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int mod=1000000007;
long long a,b;
int n;
long long pow(long long a,long long b)
{
long long res=1;
while(b)
{
if (b&1) res=(res*a)%mod;
a=(a*a)%mod;
b>>=1;
}
return res;
}
long long mul(int n)
{
long long t[2][2]={1,1,1,0};//相当于pow中的a
long long ans[2][2]={1,0,0,1};//存最后的结果
long long tmp[2][2]; // 临时的
while(n)
{
if (n&1)
{
for(int i=0;i<2;i++)
for(int j=0;j<2;j++)
tmp[i][j]=ans[i][j],ans[i][j]=0;
for(int i=0;i<2;i++)
for(int j=0;j<2;j++)
for(int k=0;k<2;k++)
ans[i][j]=(ans[i][j]+tmp[i][k]*t[k][j])%(mod-1);
}
for(int i=0;i<2;i++)
for(int j=0;j<2;j++)
{ tmp[i][j]=t[i][j]; t[i][j]=0;}
for(int i=0;i<2;i++)
for(int j=0;j<2;j++)
for(int k=0;k<2;k++)
t[i][j]=(t[i][j]+tmp[i][k]*tmp[k][j])%(mod-1);
n>>=1;
}
return (pow(a,ans[1][1])*pow(b,ans[1][0]))%mod;
}
int main()
{
while(~scanf("%lld%lld%d",&a,&b,&n))
{
if (n==0) printf("%lld\n",a%mod);
else if (n==1) printf("%lld\n",b%mod);
else printf("%lld\n",mul(n));
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: