P1306 斐波那契公约数

ぃ、小莉子 提交于 2019-11-26 18:13:07

题目描述

对于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<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

const int N=10000010;
const int mod=1e8;

long long n,m;

struct no {
	long long a[3][3];
	long long r,c;
};

no mul(no x,no y) {
	no p;
	memset(&p,0,sizeof(p));
	for(int i=0; i<x.r; i++)
		for(int j=0; j<y.c; j++)
			for(int k=0; k<x.c; k++)
				p.a[i][j]=(p.a[i][j]+x.a[i][k]*y.a[k][j])%mod;
	p.r=x.r,p.c=y.c;
	return p;
}

void fast(long long k) {
	no p,ans;
	memset(&p,0,sizeof(p));
	memset(&ans,0,sizeof(ans));
	p.r=p.c=2;
	p.a[0][0]=p.a[0][1]=p.a[1][0]=1;
	ans.r=1,ans.c=2;
	ans.a[0][0]=ans.a[0][1]=1;
	while(k) {
		if(k&1)
			ans=mul(ans,p);
		p=mul(p,p);
		k>>=1;
	}
	printf("%lld\n",ans.a[0][0]);
}

long long gcd(long long a,long long b) {
	if(a<b)
		swap(a,b);
	if(a%b==0)
		return b;
	else
		return gcd(b,a%b);
}

int main() {
	scanf("%lld%lld",&n,&m);
	n=gcd(n,m);
	if(n<=2)
		printf("1\n");
	else
		fast(n-2);
	return 0;
}

 

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!