辗转相除法+拓展gcd+中国剩余定理+拓展中国剩余定理详解

【0.注释】

1.[a / b] 表示向下取整
2.inv(a, b) 表示a在模b意义下的乘法逆元

【1.辗转相除法】

在这里插入图片描述

【代码实现】

typedef long long ll;
inline ll gcd(ll a, ll b) {
	return b == 0 ? a : gcd(b, a % b);
}

【2.拓展gcd】

在这里插入图片描述

【代码实现】

typedef long long ll;
inline pair<ll, ll> exgcd(ll a, ll b) {
	if (!b) return pair<ll, ll>(1, 0);
	register pair<ll, ll> temp = exgcd(b, a % b);
	return pair<ll, ll>(temp.second, temp.first - a / b * temp.second);
}

【3.中国剩余定理】

【4.拓展中国剩余定理】

在这里插入图片描述在这里插入图片描述

【代码实现】

typedef long long ll;
inline pair<ll, ll> exgcd(ll a, ll b) {
	if (!b) return pair<ll, ll>(1, 0);
	register pair<ll, ll> temp = exgcd(b, a % b);
	return pair<ll, ll>(temp.second, temp.first - a / b * temp.second);
}
inline ll excrt(int n) {
	register ll aa = a[1], bb = b[1];
	for (register int i = 2; i <= n; ++i) {
		register ll d = aa > a[i] ? gcd(aa, a[i]) : gcd(a[i], aa);
		register pair<ll, ll> temp = exgcd(aa / d, a[i] / d);
		while (temp.first < 0) temp.first += a[i] / d;
		if ((b[i] - bb) % d) return -1;
		register ll p = a[i] / d;
		register ll lcm = aa * p;
		bb = ((temp.first * (b[i] - bb) / d % p + p) % p * aa % lcm + bb) % lcm;
		aa = lcm;
	}
	return bb;
}
发布了40 篇原创文章 · 获赞 2 · 访问量 3229

猜你喜欢

转载自blog.csdn.net/weixin_44211980/article/details/104078388