1 2 3 4 5 6 7 8 9 10 11
| void exgcd(ll a,ll b,ll &x,ll &y) { if(!b) return x=1,y=0,void(); exgcd(b,a%b,x,y);tie(x,y)=mp(y,x-a/b*y); } ll inv(ll a,ll p) { ll x,y;exgcd(a,p,x,y); return (x%p+p)%p; } pii crt(ll a1,ll b1,ll a2,ll b2) { return mp(a1*a2,(a2*inv(a2,a1)*b1+a1*inv(a1,a2)*b2)%(a1*a2)); }
|
excrt:
1 2 3 4 5 6 7 8 9 10 11 12
| ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;} pii exgcd(ll a,ll b) { if(!b) return {1,0}; auto[x,y]=exgcd(b,a%b); return {y,x-a/b*y}; } pii excrt(pii o1,pii o2) { auto[a1,m1]=o1;auto[a2,m2]=o2; ll g=gcd(m1,m2),l=m1/g*m2; auto[l1,l2]=exgcd(m1/g,m2/g); return {(a1+(a2-a1)/g*l1*m1)%l,l}; }
|
excrt 推法:
我们要合并 x≡a1(modm1)≡a2(modm2)。
先把同余式变成标准形式:x=a1+k1m1=a2+k2m2,移项得 k1m1−k2m2=a2−a1,判完无解后利用 exgcd 求出 k1,k2,即可求出 x。
exgcd 推法:
给定 (a,b),我们需要求出满足 xa+yb=gcd(a,b) 的一组 (x,y)。
设 c=amodb,现在假设我们已知 ub+vc=gcd(a,b) 的一组 (u,v),试图推出 (x,y)。
显然 c=a−[ba]b,代入,ub+va−v[ba]b=gcd(a,b),va+(u−v[ba])b=gcd(a,b),即 (x,y)=(v,u−v[ba])。
代码里记得写 u-a/b*v,因为要下取整。