luoguP1306 斐波那契公约数
令\(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}
\therefore\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;
}