Luogu1306 斐波那契公约数

版权声明:大佬您能赏脸,蒟蒻倍感荣幸,还请联系我让我好好膜拜。 https://blog.csdn.net/ShadyPi/article/details/83541519

原题链接:https://www.luogu.org/problemnew/show/P1306

斐波那契公约数

题目描述

对于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

说明

用递归&递推会超时

用通项公式也会超时

题解

结论:
g c d ( F [ n ] , F [ m ] ) = F [ g c d ( n , m ) ] gcd(F[n],F[m])=F[gcd(n,m)]

然后愉快的矩乘~~

代码
#include<bits/stdc++.h>
using namespace std;
const int mod=1e8,N=2;
struct sd{int sq[N+1][N+1];}c,r,one,mat;
int n,m;
int sq[N+1][N+1]={{0,0,0},{0,1,1},{0,1,0}};
sd operator*(sd a,sd b)
{
	for(int i=1,j,k;i<=N;++i)for(j=1;j<=N;++j)for(c.sq[i][j]=0,k=1;k<=N;++k)
	(c.sq[i][j]+=1ll*a.sq[i][k]*b.sq[k][j]%mod)%=mod;
	return c;
}
sd power(sd a,int p){for(r=one;p;p>>=1,a=a*a)if(p&1)r=r*a;return r;}
void in(){scanf("%d%d",&n,&m);}
void ac()
{
	for(int i=1;i<=N;++i)one.sq[i][i]=1;
	for(int i=1;i<=N;++i)for(int j=1;j<=N;++j)mat.sq[i][j]=sq[i][j];
	printf("%d",power(mat,__gcd(n,m)-1).sq[1][1]);
}
int main(){in(),ac();}

猜你喜欢

转载自blog.csdn.net/ShadyPi/article/details/83541519
今日推荐