洛谷 P1306 斐波那契公约数 题解
洛谷 P1306 斐波那契公约数 题解
题意
设
思路
定理
引理 1
证明 根据斐波那契数列的递推式,有
观察到
与 结构相同,于是可以递推下去,直到 中 ,于是 等于
引理 2(更相减损术) 设
由引理 2 也可以得到推论
引理 3
证明 由递推式和引理 2 得
于是一直递推下去可以得到
下面证明整个定理。
证明
由引理 3 和
继续递归下去,则有
代码
/*
https://www.luogu.com.cn/problem/P1306
P1306 斐波那契公约数
*/
#include <cassert>
#include <iostream>
#include <algorithm>
#define f(x, y, z) for (int x = (y); x <= (z); ++x)
using namespace std;
typedef long long ll;
int constexpr MOD = 1e8;
int n, m;
inline int &AddEq(int &a, int const &b) { return (a += b) >= MOD ? (a -= MOD) : a; }
inline int Mul(int const &a, int const &b) { ll r = 1ll * a * b; return r >= MOD ? r % MOD : r; }
struct Matrix {
int a[3][3], r, c;
} A, B, I, E;
Matrix operator*(Matrix const &a, Matrix const &b) {
assert(a.c == b.r);
Matrix c = E;
c.r = a.r, c.c = b.c;
f(i, 1, c.r) f(j, 1, c.c) f(k, 1, a.c)
AddEq(c.a[i][j], Mul(a.a[i][k], b.a[k][j]));
return c;
}
Matrix ksm(Matrix a, int x) {
Matrix res = I;
while (x) {
if (x & 1) res = res * a;
a = a * a;
x >>= 1;
}
return res;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
cin >> n >> m;
n = __gcd(n, m);
if (n == 1 || n == 2) return cout << 1 << '\n', 0;
I.r = I.c = 2, I.a[1][1] = I.a[2][2] = 1;
A.r = 2, A.c = 1, A.a[1][1] = A.a[2][1] = 1;
B.r = B.c = 2, B.a[1][1] = B.a[1][2] = B.a[2][1] = 1;
A = ksm(B, n - 2) * A;
cout << A.a[1][1] << '\n';
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!