定義一數列$F$為:
$F_1=1, F_2=2$。
$F_n=F_n-1+F_n-2$。
給定兩正整數$a, b$,求$gcd(F_a, F_b)$
$a, b\le 10^{18}$
$F$其實就是費式數列,只是被位移了一格
先讓他變回正常的費式數列$f(f_1=1,f_2=1)$,此時$F_n=f_{n+1}$。
然後費式數列有個性質:
$$gcd(f_n, f_m)=f_{gcd(n, m)}$$
推導過程需要用蠻多其他定理的,
總之,這樣就等同於求數列某項,直接矩陣快速冪就可以了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
   | 
 
 
 
 
 
 
 
 
 
  #include <bits/stdc++.h> using namespace std;
  #define EmiliaMyWife ios::sync_with_stdio(0); cin.tie(NULL); using ll = int64_t; const int MOD     = 1e9+7;
 
  using mat = vector<vector<ll>>;
  mat operator*(mat &a, mat &b) { 	mat res(2, vector<ll>(2)); 	for(int i = 0; i < 2; i++) 		for(int j = 0; j < 2; j++) 			for(int k = 0; k < 2; k++) 				res[i][j] = (res[i][j] + a[i][k] * b[k][j]) % MOD; 	return res; }
  int get(ll n) { 	mat a = {{1, 1}, {1, 0}}, res = {{1, 0}, {0, 1}}; 	for(; n; n>>=1, a = a * a) 		if(n & 1) 			res = res * a; 	return res[1][0]; }
  signed main() { 	EmiliaMyWife
  	ll n, m; 	cin >> n >> m; 	cout << get(__gcd(n + 1, m + 1)) << '\n';
  	return 0; }
 
  |