斐波那契公约数(luogu 1306)

Posted qseer

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了斐波那契公约数(luogu 1306)相关的知识,希望对你有一定的参考价值。

题目描述

对于Fibonacci数列:1,1,2,3,5,8,13......大家应该很熟悉吧~~~但是现在有一个很“简单”问题:第n项和第m项的最大公约数是多少?

Update:加入了一组数据。

输入输出格式

输入格式:

 

两个正整数n和m。(n,m<=10^9)

注意:数据很大

 

输出格式:

 

Fn和Fm的最大公约数。

由于看了大数字就头晕,所以只要输出最后的8位数字就可以了。

 

输入输出样例

输入样例
4 7
输出样例
1

说明

用递归&递推会超时

用通项公式也会超时


 

 

code

#include<stdio.h>
#include<string.h>
#include<algorithm>
#define ll long long 
using namespace std;
const int P=1e8;
struct node {
    ll mp[3][3];
    int h,l;
}p,ans;

int gcd(int x,int y)
{
    if(x<y) swap(x,y);
    if(x%y==0) return y;
    else return gcd(y,x%y);
}

node mul(node x,node y) {
    node tep;
    memset(&tep,0,sizeof(tep));
    for(int i=0;i<x.h;++i) 
        for(int j=0;j<y.l;++j) 
            for(int k=0;k<x.l;++k) 
                tep.mp[i][j]=(tep.mp[i][j]+x.mp[i][k]*y.mp[k][j])%P;
    tep.h=x.h,tep.l=y.l;
    return tep;
}

int juc(ll k)
{
    ans.mp[0][0]=ans.mp[0][1]=1;
    ans.h=1,ans.l=2;
    p.mp[0][0]=p.mp[0][1]=p.mp[1][0]=1;
    p.h=p.l=2;
    while(k) {
        if(k&1) ans=mul(ans,p);
        p=mul(p,p);
        k>>=1;
    }
    return ans.mp[0][0];
}

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

 



以上是关于斐波那契公约数(luogu 1306)的主要内容,如果未能解决你的问题,请参考以下文章

P1306 斐波那契公约数

洛谷P1306 斐波那契公约数

P1306 斐波那契公约数

P1306 斐波那契公约数

斐波那契矩阵快速幂模板斐波那契公约数

斐波那契公约数的相关证明