题目描述
对于Fibonacci数列:1,1,2,3,5,8,13…大家应该很熟悉吧~~~但是现在有一个很“简单”问题:第n项和第m项的最大公约数是多少?
Update:加入了一组数据。
输入输出格式
输入格式:
两个正整数n和m。(n,m<=10^9)
注意:数据很大
输出格式:
Fn和Fm的最大公约数。
由于看了大数字就头晕,所以只要输出最后的8位数字就可以了。
输入输出样例
输入样例#1:
4 7
输出样例#1:
1
说明
用递归&递推会超时
用通项公式也会超时
斐波拉契数列有这样一个性质: ,于是就可以矩阵递推了。时间复杂度
#include<cstdio>
#include<cstring>
const int mod=1e8;
int gcd(int n,int m){return m?gcd(m,n%m):n;}
int p,f[2]={0,1},a[2][2]={{0,1},{1,1}};
void mul()
{
int c[2];memset(c,0,sizeof(c));
for(int i=0;i<=1;i++)
for(int j=0;j<=1;j++)
c[i]=(c[i]+1ll*f[j]*a[j][i])%mod;
memcpy(f,c,sizeof(c));
}
void mulself()
{
int c[2][2];memset(c,0,sizeof(c));
for(int i=0;i<2;i++)
for(int j=0;j<2;j++)
for(int k=0;k<2;k++)
c[i][j]=(c[i][j]+1ll*a[i][k]*a[k][j])%mod;
memcpy(a,c,sizeof(c));
}
void qpow()
{
for(;p;p>>=1)
{
if(p&1)mul();
mulself();
}
printf("%d\n",f[0]);
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
p=gcd(n,m);
qpow();
return 0;
}
总结
这个性质很关键,然后矩阵那里也有点不太会写了。