您的位置:首页 > 其它

HDOJ 题目4549 M斐波那契数列(数学,矩阵快速幂,费马小定理)

2014-08-18 19:13 627 查看

M斐波那契数列

Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)

Total Submission(s): 1386    Accepted Submission(s): 396


[align=left]Problem Description[/align]
M斐波那契数列F
是一种整数数列,它的定义如下:

F[0] = a

F[1] = b

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

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

[align=left]Input[/align]
输入包含多组测试数据;

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

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

[align=left]Sample Input[/align]

0 1 0
6 10 2

 

[align=left]Sample Output[/align]

0
60

 

[align=left]Source[/align]
2013金山西山居创意游戏程序挑战赛——初赛(2)

 

[align=left]Recommend[/align]
liuyiding   |   We have carefully selected several similar problems for you:  4959 4958 4957 4956 4955 
 
思路:

1. 首先得出封闭形式:

F
=a  (n=0)

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

2. 发现1000000007是质数,遂用费马小定理,得

F
%m=a^(Fib[n-1]%(m-1))*b^(Fib
%(m-1))%m

3. f
%(m-1)的计算用矩阵快速幂

4. a^x的计算用快速幂

我的ac代码

说实话那个p矩阵为毛那么写,我还是真的不知道,求路过的大神帮一把

#include<stdio.h>
#include<string.h>
#include<math.h>
#define mod 1000000007
struct s
{
__int64 mp[2][2];
};
struct s p={
1,1,
1,0,
};
struct s I={
1,0,
0,1,
};
struct s muti(struct s a,struct s b)
{
struct s c;
int i,j,k;
memset(c.mp,0,sizeof(c.mp));
for(i=0;i<2;i++)
for(j=0;j<2;j++)
{
//c.mp[i][j]=0;
for(k=0;k<2;k++)
{
c.mp[i][j]+=(a.mp[i][k]*b.mp[k][j])%(mod-1);

}c.mp[i][j]%=(mod-1);
}
return c;
}
struct s mutip(__int64 n)
{
struct s tp=p,ti=I;
//printf("%I64d %I64d %I64d\n",ti.mp[1][1],ti.mp[1][0],n);
while(n)
{
/*if(n&1)//这种快速幂写法也可以
{
ti=muti(ti,tp);
n--;
}
else
{
tp=muti(tp,tp);
n/=2;
}*/
//	printf("%I64d %I64d %I64d\n",ti.mp[1][1],ti.mp[1][0],n);
if(n&1)
{
ti=muti(ti,tp);
//printf("%I64d %I64d %I64d\n",ti.mp[1][1],ti.mp[1][0],n);
}
tp=muti(tp,tp);
n>>=1;
}
return ti;
}
__int64 qpow(__int64 a,__int64 b)
{
__int64 s=1;
while(b)
{
if(b&1)
s=s*a%mod;
a=a*a%mod;
b>>=1;
}
return s;
}
int main()
{
__int64 a,b,n;
while(scanf("%I64d%I64d%I64d",&a,&b,&n)!=EOF)
{
struct s pi=mutip(n);
printf("%I64d\n",(qpow(a,pi.mp[1][1])*qpow(b,pi.mp[1][0]))%mod);
//printf("%I64d %I64d\n",pi.mp[1][1],pi.mp[1][0]);
}
}


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