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;
}
posted @ 2019-10-14 21:00  wuhan2005  阅读(91)  评论(0编辑  收藏  举报