扩展中国剩余定理学习笔记

给定 n 组非负整数 ai,bi ,求解关于 x 的方程组的最小非负整数解。
{xb1 (mod a1)xb2 (mod a2)...xbn (mod an)

首先我们看一下只有 1 个方程的情况:
xb1 (mod a1)
那么 x 就是 b1moda1

然后是 2 个方程的情况:
{xb1 (mod a1)xb2 (mod a2)
可以改写成 {x=b1+X×a1x=b2+Y×a2
然后就知道 b1+X×a1=b2+Y×a2。所以 a1×X+a2×(Y)=b2b1
这个可以用 exgcd 求。具体方法不赘述。
然后求出 X 的一个解 X0,然后就知道 X 的通解 X=X0+k×(b2b1)×a2gcd(a1,a2)。然后令 p=(b2b1)×a2gcd(a1,a2),就可以求出 X 的最小正解 X1=(X0modp+p)modp。此时新的 A=lcm(a1,a2)B=(X1×a1+b1)modA

然后是多个方程的情况:
每 2 个合并成 1 个,直到只剩下一个同余方程。时间复杂度 O(nlogw),其中 w 是值域。

inline ll lcm(ll a,ll b){
	return a*b/__gcd(a,b);
}
inline void exgcd(ll &x,ll &y,ll a,ll b){
	if(!b){x=1;y=0;return;}
	exgcd(y,x,b,a%b);y-=a/b*x;
}
ll n,A,B;
int main(){
	n=rd();A=rd();B=rd();
	for(ll i=1,a,b,x,y;i<n;i++){
		a=rd();b=rd();
		ll g=__gcd(a,A),mod=A/g;
		exgcd(x,y,a,A);
		x=((x*(B-b)/g)%mod+mod)%mod;
		A=lcm(a,A);
		B=(a*x+b)%A;
	}
	printf("%lld",(long long)(B%A));
	return 0;
}
posted @   lrxQwQ  阅读(21)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示