题解
2024-07-08 18:47:46
发布于:广东
42阅读
0回复
0点赞
先看这道题的歪解
可知当时,.
.
又
(辗转相除法).
又
(辗转相除法)
(辗转相除法)
(辗转相除法)
(辗转相除法)
,
.
嗯?怎么有点眼熟?
那这样不就可以和普通的求最大公因数一样了吗!
.
所以,我们只需要求的值就行了
矩阵快速幂:
#include <iostream>
#include <cstdio>
#include <memory.h>
using namespace std;
const int mod = 1e8;
struct node{
	long long a[2][2];
	node(){
		memset(a, 0, sizeof(a));
	}
	node operator * (const node &b) const{
		node tmp;
		for(int i = 0; i < 2; i++){
			for(int j = 0; j < 2; j++){
				for(int k = 0; k < 2; k++){
					tmp.a[i][j] = (a[i][k] * b.a[k][j] % mod + tmp.a[i][j]) % mod;
				}
			}
		}return tmp;
	}
};
node pow(node n, int k){
	node tmp;
	tmp.a[0][0] = tmp.a[1][1] = 1;
	while(k){
		if(k & 1) tmp = tmp * n;
		n = n * n, k >>= 1;
	}return tmp;
}
int gcd(int n, int m){
    if(m == 0) return n;
    return gcd(m, n % m);
}
int main(){
	int n, m;
	cin >> n >> m;
    if(n < m) swap(n, m);
    n = gcd(n, m);
	node a;
	a.a[0][0] = a.a[0][1] = a.a[1][0] = 1;
	cout << pow(a, n).a[1][0];
	return 0;
}
时间复杂度:.
乘法分治:
#include <iostream>
#include <cstdio>
#include <map>
#include <algorithm>
#define int long long
using namespace std;
map <int, int> a;
const int mod = 1e9 + 7;
int fib(long long n){
	if(a[n]) return a[n];
	if(n % 2 == 1){
		int l = fib(n / 2), r = fib((n / 2) + 1);
		return a[n] = (l * l + r * r) % mod;
	}
	else return a[n] = fib(n / 2) * (fib((n / 2) - 1) + fib((n / 2) + 1)) % mod;
}
signed main(){
    a[2] = a[1] = 1;
	long long n, m;
	cin >> n >> m;
	cout << fib(__gcd(n, m));
	return 0;
}
时间复杂度:.
全部评论 1
- 看不懂 - 2024-07-06 来自 广东 0- 纯数学知识👍 - 2024-07-06 来自 广东 0
- gcd是指两个数的最大公因数 - 2024-07-06 来自 广东 0
- 我知道 - 2024-07-06 来自 广东 0
 










有帮助,赞一个