• P1306 斐波那契公约数


    首先:

    F[1] = F[1] = 1 

    F[i] = F[i - 1] + F[i - 2] (i > 2)

    假设n > m

    设 F[m] = a , F[m + 1] = b

    F[m + 2] = a + b

    F[m + 3] = a + b * 2 = a + F[3] * b

    F[m + 4] = 2 * a + 3 * b = F[3] * a + F[3] * (F[3] + F[2]) * b = F[3] * a + F[4] * b

    F[m + 5] = (F[3] + F[2]) * a + (F[4] + F[3]) * b = F[4] * a + F[5] * b

    ........

    F[n] =  F[n - m - 1] * F[m] + F[n - m] * F[m + 1]

    所以GCD(F[n] , F[m]) = GCD(F[n - m - 1] * F[m] + F[n - m] * F[m + 1],F[m])

    由于F[n - m - 1] * F[m] 是 F[m] 的倍数,所以去掉

    就变成了GCD(F[n] , F[m]) = GCD(F[n - m - 1] * F[m] + F[n - m] * F[m + 1],F[m]) = GCD(F[n - m] * F[m + 1] , F[m])

    由于GCD(F[m + 1] , F[m]) = 1 , 所以GCD(F[n - m] * F[m + 1] , F[m]) = GCD(F[n - m]  , F[m])

    也就是:

    GCD(F[n] , F[m]) = GCD(F[n - m] , F[m]) = GCD(F[n - 2 * m] , F[m]) = ....

    然后通过不挺的执行以上操作就会变成:

    GCD(F[n] , F[m]) =  GCD(F[n % m] , F[m])

    接下来设mm = n % m , 同样进行操作,就变成了:

    GCD(F[n % m] , F[m]) = GCD(F[mm] , F[m % mm]) ....

    这么一看其实就是辗转相除,当其中有一个变为0的时候,另外一个不为0的就是答案了

    也就是F[GCD(n ,m)]

    矩阵快速幂一波就好了

    AC代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn =  1e6 + 10;
    #define ll long long
    #define int long long
    int gcd(int a,int b){return !b?a:gcd(b,a%b);}
    const int MAXN = 2;
    struct Matrix
    {
        ll mat[MAXN][MAXN];
    };
    Matrix P;
    Matrix I; //单位矩阵
    Matrix Mul_Matrix(Matrix a, Matrix b , ll mod)
    {
        Matrix c;
        for(int i = 0 ; i < MAXN ; i ++)
            for(int j = 0 ; j < MAXN ; j ++)
            {
                c.mat[i][j] = 0;
                for(int k = 0 ; k < MAXN ; k ++)
                {
                    c.mat[i][j] += (a.mat[i][k] * b.mat[k][j]) % mod;
                    c.mat[i][j] %= mod;
                }
            }
        return c;
    }
    Matrix pow_mod_Matrix(Matrix P , ll n , ll mod)
    {
        Matrix ans = I, b = P;
        while(n)
        {
            if(n & 1) ans = Mul_Matrix(ans , b , mod);
            n >>= 1;
            b = Mul_Matrix(b , b , mod);
        }
        return ans;
    }
    void Matrix_init()
    {
        for(int i = 0 ; i < MAXN ; i ++) I.mat[i][i] = 1;
        P.mat[0][0] = P.mat[0][1] = P.mat[1][0] = 1;
    }
    const int mod = 1e8;
    signed main()
    {
        ios;
        cin.tie(0);
        int n , m;
        cin >> n >> m;
        Matrix_init();
        int re = gcd(n , m);
        if(re <= 2) cout << "1
    ";
        else cout << pow_mod_Matrix(P , re - 1 , mod).mat[0][0] << '
    ';
        return 0;
    }
  • 相关阅读:
    无缝轮播图
    瀑布流之ajax
    进阶版轮播图
    桌面特效
    3D模型文字动画
    Razor 常用方法
    easyui常用
    C#
    Redis设置记录
    日志三剑客ELK
  • 原文地址:https://www.cnblogs.com/GoodVv/p/13681951.html
Copyright © 2020-2023  润新知