luoguP1306 斐波那契公约数

两盒软妹~` 提交于 2019-12-01 08:48:15

\(n<=m\)

\[ \begin{eqnarray}f[n+2]&=&f[n]*f[1]+f[n+1]*f[2]\\ f[n+3]&=&f[n]*f[2]+f[n+1]*f[3]\\ &......&\\ f[m]&=&f[n]*f[m-n-1]+f[n+1]*f[m-n] \end{eqnarray} \]

\[ \begin{align} \gcd(f[n],f[m])&=\gcd(f[n],f[n]*f[m-n-1]+f[n+1]*f[m-n])\\ &=\gcd(f[n],f[n+1]*f[m-n])\\ &=\gcd(f[n],f[m-n])\\ &=\gcd(f[n],f[m\%n]) \end{align} \]

就是辗转相除啦!
\[ \begin{align} \gcd(f[n],f[m])=f[\gcd(n,m)] \end{align} \]

然后用矩阵快速幂优化即可.

#pragma GCC optimize(3)
#include<bits/stdc++.h>
#define il inline
#define rg register
#define gi read<int>
using namespace std;
const int mod=1e8;
template<class TT>
il TT read() {
    TT o = 0, fl = 1; char ch = getchar();
    while (!isdigit(ch)) fl ^= ch == '-', ch = getchar();
    while (isdigit(ch)) o = o * 10 + ch - '0', ch = getchar();
    return fl ? o : -o;
}
int n, m;
struct Matrix {
    int a[2][2];
    Matrix() { memset(a, 0, sizeof a); }
    il int* operator [] (int x) { return a[x]; }
    il Matrix operator * (Matrix rhs) const {
        Matrix c;
        for (int k = 0; k < 2; ++k)
            for (int i = 0; i < 2; ++i)
                for(int j = 0; j < 2; ++j)
                    (c[i][j] += (1ll * a[i][k] * rhs[k][j]) % mod) %= mod;
        return c;
    }
} S, T;
int main() {
    n = gi(), m = gi();
    while (m) n %= m, n ^= m ^= n ^= m;
    T[0][0] = T[1][0] = T[0][1] = S[0][1] = 1;
    while (n) {
        if (n & 1) S = S * T;
        T = T * T; n >>= 1;
//      printf("%d %d\n", S[0][0], S[0][1]);
    }
    printf("%d", S[0][0]);
    return 0;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!