斐波那契公约数

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

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

引理1:gcd ( F[n+1] , F[n] ) = 1

gcd(F[n+1],F[n])

=gcd(F[n+1]-F[n],F[n])

=gcd(F[n],F[n-1])

=gcd(F[2],F[1])

=1

 

引理2:F[m+n] = F[m-1] * F[n] + F[m] * F[n+1]

 

太长了

 

引理3:gcd ( F[n+m] , F[n] ) = gcd ( F[n] , F[m] )

gcd(F[n+m],F[n])

=gcd(F[n+1]F[m]+F[n]F[m-1],F[n])

=gcd(F[n+1]F[m],F[n])

=gcd(F[n+1],F[n])*gcd(F[m],F[n])

=gcd(F[m],F[n]);

 

由辗转相除法则原结论得证


所以只用求f[gcd(n,m)]即可,由于n,m太大,要用矩阵快速幂

 

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#define ll long long
using namespace std;
const int mod=1e8;
inline int read(){
    int x=0,k=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-') k=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
    return k*x;
}
struct matrix{
    ll m[3][3];
}ans,res;
matrix mul(matrix a,matrix b){
    matrix tmp;
    for(int i=1;i<=2;i++)
        for(int j=1;j<=2;j++)
            tmp.m[i][j]=0;
    for(int i=1;i<=2;i++)
        for(int j=1;j<=2;j++)
            for(int k=1;k<=2;k++)
                tmp.m[i][j]=(tmp.m[i][j]+a.m[i][k]%mod*b.m[k][j]%mod)%mod;
    return tmp;
}
void poww(ll x){
    while(x){
        if(x&1) ans=mul(ans,res);
        res=mul(res,res);
        x>>=1;
    }
}
ll gcd(ll x,ll y){
    return y?gcd(y,x%y):x;
}
int main(){
//    freopen(".in","r",stdin);
//    freopen(".out","w",stdout);
    ll n,m;
    n=read();m=read();
    n=gcd(n,m);
    ans.m[1][1]=1;ans.m[1][2]=1;
    res.m[1][1]=1;res.m[2][1]=1;res.m[1][2]=1;
    if(n==1||n==2){
        cout<<1;
        return 0;
    }
    poww(n-2);
    cout<<ans.m[1][1]%mod;    
    return 0;
}
View Code

 

posted @ 2018-10-22 22:10  滑稽的大白兔  阅读(252)  评论(0编辑  收藏  举报