【Luogu】P1306 斐波那契公约数 题解

原题链接

重要性质:\(gcd(fib[x],fib[y])=fib[gcd(x,y)]\)

怎么证呢?

证明:先证明斐波那契数列相邻两项是互素的。

  • 反证法。若不互素,设\(x=gcd(fib[i],fib[i-1]),x>1\)

    \(x|fib[i],x|fib[i-1]\)

    又因为\(fib[i-2]=fib[i]-fib[i-1]\)

    所以\(x|fib[i-2]\)

    一直往前推,直到\(x|fib[2]\)

    又因为\(fib[2]=1\)

    所以\(x=1\),矛盾!

接着,证明\(fib[n]=fib[m] fib[n-m+1]+fib[m-1] fib[n-m]\)

  • \(fib[n]=fib[n-1]+fib[n-2]\)

    \(fib[n]=2fib[n-2]+fib[n-3]\)

    \(fib[n]=3fib[n-3]+2fib[n-4]\)

    ...

    \(fib[n]=fib[m] fib[n-m+1]+fib[m-1] fib[n-m]\)

最后,来到了对原公式的证明:

  • \(gcd(fib[x],fib[y])\)

    \(=gcd(fib[y]fib[x-y+1]+fib[y-1]fib[x-y],fib[y])\)

    \(=gcd(fib[x-y],f[y])\)(因为\(fib[y-1]\)\(fib[y]\)互质)

    以此递推下去,得:

    \(=gcd(fib[x mod y],f[y])\)

    这不是辗转相除吗?以此类推,最后会得到:

    \(=gcd(fib[0],fib[gcd(x,y)])\)

    \(=fib[gcd(x,y)]\)

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int mod=1e8;
struct Matrix{
    long long matrix[105][105];
    int x,y;
    Matrix(const long long a[105][105],int xx,int yy){
        for(int i=1;i<=xx;i++){
            for(int j=1;j<=yy;j++){
                matrix[i][j]=a[i][j];
            }
        }
        x=xx,y=yy;
    }
    Matrix(int fill,int xx,int yy){
        for(int i=1;i<=xx;i++){
            for(int j=1;j<=yy;j++){
                matrix[i][j]=fill;
            }
        }
        x=xx,y=yy;
    }
    Matrix(){
        x=y=0;
        memset(matrix,0,sizeof(matrix));
    }
    Matrix operator*(const Matrix& a) const{
        Matrix ans;
        for(int i=1;i<=x;i++){
            for(int j=1;j<=a.y;j++){
                ans.matrix[i][j]=0;
                for(int k=1;k<=y;k++){
                    ans.matrix[i][j]+=matrix[i][k]*a.matrix[k][j];
                    ans.matrix[i][j]%=mod;
                }
            }
        }
        ans.x=x,ans.y=a.y;
        return ans;
    }
    Matrix operator%(const int& a) const{
        Matrix ans;
        for(int i=1;i<=x;i++){
            for(int j=1;j<=y;j++){
                ans.matrix[i][j]=matrix[i][j]%a;
            }
        }
        return *this;
    }
    Matrix operator^(const long long& a) const{
        Matrix ans(1,x,y),power(*this);
        for(int i=1;i<=x;i++){
            for(int j=1;j<=y;j++){
                if(i!=j) ans.matrix[i][j]=0;
            }
        }
        long long tmp=a;
        while(tmp){
            if(tmp&1){
                ans=ans*power;
                ans=ans%mod;
            }
            power=power*power;
            tmp>>=1;
            power=power%mod;
        }
        return ans;
    }
}m;
long long n,k,p;
int t;
const long long d[105][105]={\
{0,0,0},
{0,1,1},
{0,1,0}
};
Matrix c(1,2,1);
int gcd(int a,int b){
    return b==0?a:gcd(b,a%b);
}

int main(){
    Matrix m(d,2,2);
    cin>>n>>p;
    k=gcd(n,p);
    if(k<=2) {
        cout<<1<<endl;
        return 0;
    }
    Matrix ans=c*(m^(k-1));
    cout<<ans.matrix[1][1]<<endl;
    return 0;
}

posted @ 2020-01-19 17:10  Zesty_Fox  阅读(164)  评论(1编辑  收藏  举报