扩展欧几里得、中国剩余定理和扩展中国剩余定理

1 扩展欧几里得算法

扩展欧几里得算法主要可以解决:
·求乘法逆元
·求解同余方程/二元一次方程

其中,求乘法逆元可以转化成求解同余方程。

1.1求解方程 a x + b y = g c d ( a , b ) ax+by=gcd(a,b) ax+by=gcd(a,b)的一组特解

先考虑以下二元一次方程:

a x + b y = g c d ( a , b )     ( 1 ) ax+by=gcd(a,b) \qquad\qquad\qquad\qquad\qquad\ \ \ (1) ax+by=gcd(a,b)   (1)

b x ′ + ( a % b ) y ′ = g c d ( b , a % b ) = g c d ( a , b ) ( 2 ) bx'+(a\%b)y'=gcd(b,a\%b)=gcd(a,b) \qquad(2) bx+(a%b)y=gcd(b,a%b)=gcd(a,b)(2)

. . . ... ...

g c d ( a , b ) x ′ ′ + 0 ∗ y ′ ′ = g c d ( a , b )         ( 3 ) gcd(a,b)x''+0*y''=gcd(a,b)\qquad\qquad\ \ \ \ \ \ \ (3) gcd(a,b)x+0y=gcd(a,b)       (3)

对于方程 ( 3 ) (3) (3),显然它的一个解是 x ′ ′ = 1 , y ′ ′ = 0 ; x''=1,y''=0; x=1,y=0;

想要求解方程 ( 1 ) (1) (1),我们就要找到方程 ( 1 ) ( 2 ) (1)(2) (1)(2) x , y x,y x,y x ′ , y ′ x',y' x,y之间的关系。

将方程 ( 2 ) (2) (2)变形:

b x ′ + ( a % b ) y ′ = g c d ( a , b ) bx'+(a\%b)y'=gcd(a,b) bx+(a%b)y=gcd(a,b)

b x ′ + ( a − ⌊ a / b ⌋ b ) y ′ = g c d ( a , b ) bx'+(a-\lfloor a/b \rfloor b)y'=gcd(a,b) bx+(aa/bb)y=gcd(a,b)

将含 a a a b b b的项合并,得到

a y ′ + b [ ( x ′ − ⌊ a / b ⌋ ) y ′ ] = g c d ( a , b )            ( 4 ) ay'+b[(x'- \lfloor a/b \rfloor)y']=gcd(a,b)\ \ \ \ \ \ \ \ \ \ (4) ay+b[(xa/b)y]=gcd(a,b)          (4)

将其与方程 ( 1 ) (1) (1)比较:

a x + b y = g c d ( a , b )     ( 1 ) ax+by=gcd(a,b) \qquad\qquad\qquad\qquad\ \ \ (1) ax+by=gcd(a,b)   (1)

容易看出,可以取

x = y ′ x = y' x=y

y = x ′ − ⌊ a / b ⌋ y ′ y = x'- \lfloor a/b \rfloor y' y=xa/by

作为方程 ( 1 ) (1) (1)的解。

因此,可以在递归调用欧几里得算法时不断更新 x x x y y y,得到方程的一组解。

C o d e : Code: Code:

void exgcd(int a,int b,int &x,int &y)
{
	if(b == 0)
	{
		x = 1;
		y = 0;
		return;
	}
	exgcd(b,a%b,x,y);
	int x_ = x;
	x = y;
	y = x_-a/b*y;
}

1.2求出二元一次方程 a x + b y = g c d ( a , b ) ax+by=gcd(a,b) ax+by=gcd(a,b)的通解和最小正整数解

< < <结论 > > >设方程 a x + b y = g c d ( a , b ) ax+by=gcd(a,b) ax+by=gcd(a,b)有特解 x = x 0 , y = y 0 x=x_0,y=y_0 x=x0,y=y0,

则方程 a x + b y = g c d ( a , b ) ax+by=gcd(a,b) ax+by=gcd(a,b)通解形如

x = x 0 + t ∗ ( b / g c d ( a , b ) ) x=x_0+t*(b/gcd(a,b)) x=x0+t(b/gcd(a,b))

y = y 0 − t ∗ ( a / g c d ( a , b ) ) ( t ∈ Z ) y=y_0-t*(a/gcd(a,b))(t\in \mathbb{Z}) y=y0t(a/gcd(a,b))(tZ),

最小正整数解 x m i n = ( x 0 + p ) % p . x_{min}=(x_0+p)\%p. xmin=(x0+p)%p.

< < <证明 > > > ( 1.1 ) (1.1) (1.1)中,我们解出了 a x + b y = g c d ( a , b ) ax+by=gcd(a,b) ax+by=gcd(a,b)的一组通解 ( x 0 , y 0 ) (x_0,y_0) (x0,y0),设该方程的通解形如

x = x 0 + m x=x_0+m x=x0+m

y = y 0 + n y=y_0+n y=y0+n

代入方程得

a ( x 0 + m ) + b ( y 0 + n ) = g c d ( a , b ) = a x 0 + b y 0 a(x_0+m)+b(y_0+n)=gcd(a,b)=ax_0+by_0 a(x0+m)+b(y0+n)=gcd(a,b)=ax0+by0

a x 0 + a m + b y 0 + b n = a x 0 + b y 0 ax_0+am+by_0+bn=ax_0+by_0 ax0+am+by0+bn=ax0+by0

a m + b n = 0 am+bn=0 am+bn=0

a / b = − ( n / m ) = ( a / g c d ( a , b ) ) / ( b / ( g c d ( a , b ) ) ) a/b=-(n/m)=(a/gcd(a,b))/(b/(gcd(a,b))) a/b=(n/m)=(a/gcd(a,b))/(b/(gcd(a,b)))

由于 a / g c d ( a , b ) a/gcd(a,b) a/gcd(a,b) b / g c d ( a , b ) b/gcd(a,b) b/gcd(a,b)一定互质(分数为最简分数),那么 m m m n n n一定是在这个分数基础上分子分母同乘一个整数 t t t得到的,因此一定有

m = t ∗ ( b / g c d ( a , b ) ) m=t*(b/gcd(a,b)) m=t(b/gcd(a,b))

n = ( − t ) ∗ ( a / g c d ( a , b ) ) n=(-t)*(a/gcd(a,b)) n=(t)(a/gcd(a,b))

因此方程通解

x = x 0 + t ∗ ( b / g c d ( a , b ) ) x=x_0+t*(b/gcd(a,b)) x=x0+t(b/gcd(a,b))

y = y 0 − t ∗ ( a / g c d ( a , b ) ) y=y_0-t*(a/gcd(a,b)) y=y0t(a/gcd(a,b))

t ∈ Z . t\in\mathbb{Z}. tZ.

若要求出最小正整数的 x m i n x_{min} xmin,记 b / g c d ( a , b ) = p b/gcd(a,b)=p b/gcd(a,b)=p,

x ≥ 0 x\geq0 x0时, x m i n = ( x 0 + t p ) % p = x % p x_{min}=(x_0+tp)\%p=x\%p xmin=(x0+tp)%p=x%p;

x < 0 x<0 x<0时, x m i n = ( x 0 + p ) % p . x_{min}=(x_0+p)\%p. xmin=(x0+p)%p.

1.3求出二元一次方程 a x + b y = c ax+by=c ax+by=c的特解

< < <结论 > > >若方程 a x + b y = g c d ( a , b ) ax+by=gcd(a,b) ax+by=gcd(a,b)有特解 x = x 0 , y = y 0 x=x_0,y=y_0 x=x0,y=y0,

则方程 a x + b y = c ax+by=c ax+by=c c c c能被 g c d ( a , b ) gcd(a,b) gcd(a,b)整除时有特解

x = k x 0 x=kx_0 x=kx0

y = k y 0 , y=ky_0, y=ky0,

其中 k = c / g c d ( a , b ) k=c/gcd(a,b) k=c/gcd(a,b).

< < <证明 > > >通过上面 ( 1.1 ) (1.1) (1.1)的算法可以求解方程 a x + b y = g c d ( a , b ) ax+by=gcd(a,b) ax+by=gcd(a,b)的一组解 ( x 0 , y 0 ) (x_0,y_0) (x0,y0),即

a x 0 + b y 0 = g c d ( a , b ) ax_0+by_0=gcd(a,b) ax0+by0=gcd(a,b)

c / g c d ( a , b ) = k c/gcd(a,b)=k c/gcd(a,b)=k(仅当 c c c g c d ( a , b ) gcd(a,b) gcd(a,b)整除,方程有解),于是

k ( a x 0 + b y 0 ) = k ⋅ g c d ( a , b ) k(ax_0+by_0)=k·gcd(a,b) k(ax0+by0)=kgcd(a,b)

k a x 0 + k b y 0 = c kax_0+kby_0=c kax0+kby0=c

a ( k x 0 ) + b ( k y 0 ) = c a(kx_0)+b(ky_0)=c a(kx0)+b(ky0)=c

因此, x = k x 0 , y = k y 0 x=kx_0,y=ky_0 x=kx0,y=ky0是方程 a x + b y = c ax+by=c ax+by=c的一组特解

1.4求出二元一次方程 a x + b y = c ax+by=c ax+by=c的通解

< < <结论 > > >若方程 a x + b y = c ax+by=c ax+by=c有特解 x = x 1 , y = y 1 x=x_1,y=y_1 x=x1,y=y1,

则方程 a x + b y = c ax+by=c ax+by=c有通解

x = x 1 + m ∗ ( b / g c d ( a , b ) ) x=x_1+m*(b/gcd(a,b)) x=x1+m(b/gcd(a,b))

y = y 1 − m ∗ ( a / g c d ( a , b ) ) , ( m ∈ Z ) . y=y_1-m*(a/gcd(a,b)),(m\in\mathbb{Z}). y=y1m(a/gcd(a,b)),(mZ).

< < <证明 > > > a x + b y = g c d ( a , b ) ax+by=gcd(a,b) ax+by=gcd(a,b)的一组特解为 x 1 , y 1 x_1,y_1 x1,y1,那么由 ( 1.3 ) (1.3) (1.3)中的推导可知, x = k x 1 , y = k y 1 x=kx_1,y=ky_1 x=kx1,y=ky1是方程 a x + b y = c ax+by=c ax+by=c的解。

假设方程有特解形如 x ′ = k x 1 + Δ x , y ′ = k y 1 + Δ y x'=kx_1+\Delta x,y'=ky_1+\Delta y x=kx1+Δx,y=ky1+Δy,

就有

a x ′ + b y ′ = a ( k x 1 + Δ x ) + b ( k y 1 + Δ y ) = c ax'+by'=a(kx_1+\Delta x)+b(ky_1+\Delta y)=c ax+by=a(kx1+Δx)+b(ky1+Δy)=c

a k x 1 + b k y 1 + a Δ x + b Δ y = c = a k x 1 + b k y 1 akx_1+bky_1+a\Delta x+b\Delta y=c=akx_1+bky_1 akx1+bky1+aΔx+bΔy=c=akx1+bky1

a Δ x + b Δ y = 0. a\Delta x+b\Delta y=0. aΔx+bΔy=0.

类似于 ( 1.2 ) (1.2) (1.2)中的过程,可得

a / b = − ( Δ y / Δ x ) = ( a / g c d ( a , b ) ) / ( b / g c d ( a , b ) ) a/b=-(\Delta y/\Delta x)=(a/gcd(a,b))/(b/gcd(a,b)) a/b=(Δy/Δx)=(a/gcd(a,b))/(b/gcd(a,b))

因此

Δ x = m ∗ ( b / g c d ( a , b ) ) \Delta x=m*(b/gcd(a,b)) Δx=m(b/gcd(a,b))

Δ y = − m ∗ ( a / g c d ( a , b ) ) \Delta y=-m*(a/gcd(a,b)) Δy=m(a/gcd(a,b))

所以 a x + b y = c ax+by=c ax+by=c通解

x = k x 1 + Δ x = k x 1 + m ∗ ( b / g c d ( a , b ) ) x=kx_1+\Delta x=kx_1+m*(b/gcd(a,b)) x=kx1+Δx=kx1+m(b/gcd(a,b))

y = k y 1 + Δ y = k x 2 − m ∗ ( a / g c d ( a , b ) ) y=ky_1+\Delta y=kx_2-m*(a/gcd(a,b)) y=ky1+Δy=kx2m(a/gcd(a,b))

m ∈ Z . m\in\mathbb{Z}. mZ.

1.5求乘法逆元

称一个数 a a a在模 p ( g c d ( a , p ) = 1 ) p(gcd(a,p)=1) p(gcd(a,p)=1)意义下的乘法逆元 x x x为满足条件
a x ≡ 1 ( m o d   p ) ax \equiv 1 (mod\ p) ax1(mod p)的一个 x . x. x.

由同余的意义,可以将这个条件转化为

a x = k p + 1 ( k ∈ Z ) ax=kp+1(k\in \mathbb{Z}) ax=kp+1(kZ)

a x − k p = 1 ( g c d ( a , p ) = 1 ) ax-kp=1(gcd(a,p)=1) axkp=1(gcd(a,p)=1)

这时就转化为 ( 1.1 ) (1.1) (1.1)中方程 a x + b y = g c d ( a , b ) ax+by=gcd(a,b) ax+by=gcd(a,b) g c d ( a , b ) = 1 gcd(a,b)=1 gcd(a,b)=1时的情况,就可以用扩展欧几里得算法求解了.然而求出的一个解 x 0 x_0 x0有可能为负值,如求解 5 5 5在模 13 13 13意义下的乘法逆元:

5 x − 13 k = 1 5x-13k=1 5x13k=1

这时解 x = − 5 , k = − 2 x=-5,k=-2 x=5,k=2也成立。

而正确的乘法逆元为 8 8 8.此时对 x x x加上模数 13 13 13即可。

< < <证明 > > > a x 0 − k 0 p = 1 , − p < x 0 < 0 ( a , x 0 , k 0 , p ∈ Z ) ax_0-k_0p=1,-p\lt x_0 \lt 0(a,x_0,k_0,p\in\mathbb{Z}) ax0k0p=1,p<x0<0(a,x0,k0,pZ) x ′ = x 0 + p x'=x_0+p x=x0+p是一个乘法逆元。

要证明 x ′ x' x是一个 a a a的乘法逆元,只需要证明

a x ′ ≡ 1 ( m o d   p ) ax'\equiv1(mod\ p) ax1(mod p)

a x ′ = a ( x 0 + p ) = a x 0 + a p = k 0 p + 1 + a p = ( k 0 + a ) p + 1 ax'=a(x_0+p)=ax_0+ap=k_0p+1+ap=(k_0+a)p+1 ax=a(x0+p)=ax0+ap=k0p+1+ap=(k0+a)p+1

a x ′ = ( k 0 + a ) p + 1 ax'=(k_0+a)p+1 ax=(k0+a)p+1,两边同时取模得

a x ′ ≡ 1 ( m o d   p ) . □ ax'\equiv1(mod\ p).\square ax1(mod p).

为了与 x ≥ 0 x\geq0 x0的情况统一,最终对 x x x进行 x = ( x + p ) % p x=(x+p)\%p x=(x+p)%p可确保得到一个 [ 0 , p − 1 ] [0,p-1] [0,p1]的逆元。

C o d e : Code: Code:

int inv(int a,int mod)
{
	int x,y;
	exgcd(a,mod,x,y);
	return (x+mod)%mod;
}

2 中国剩余定理(CRT)

《孙子算经》中记载了一个问题:“有物不知其数,三三数之剩二,五五数之剩三,七七数之剩二。问物几何?”转化为数学语言为:

x ≡ 2 ( m o d   3 ) ( 1 ) x \equiv 2(mod\ 3)\qquad(1) x2(mod 3)(1)

x ≡ 3 ( m o d   5 ) ( 2 ) x \equiv 3(mod\ 5)\qquad(2) x3(mod 5)(2)

x ≡ 2 ( m o d   7 ) ( 3 ) x \equiv 2(mod\ 7)\qquad(3) x2(mod 7)(3)

求解 x x x。利用中国剩余定理可以解决这种问题模数之间互质的情况。(不互质可以用扩展中国剩余定理求解)

设上面三个方程的解分别为 x 1 , x 2 , x 3 x_1,x_2,x_3 x1,x2,x3,先考虑使 X = x 1 + x 2 + x 3 X=x_1+x_2+x_3 X=x1+x2+x3对于方程 ( 1 ) (1) (1)成立的条件:

x 2 , x 3 x_2,x_3 x2,x3均是 3 3 3的倍数,那么

X % 3 = ( x 1 + x 2 + x 3 ) % 3 = ( x 1 + 3 k 2 + 3 k 3 ) % 3 = x 1 % 3 = 2. X\%3=(x_1+x_2+x_3)\%3=(x_1+3k_2+3k_3)\%3=x_1\%3=2. X%3=(x1+x2+x3)%3=(x1+3k2+3k3)%3=x1%3=2.

这样,我们就找到了一个使 x 1 + x 2 + x 3 x_1+x_2+x_3 x1+x2+x3对方程 ( 1 ) (1) (1)成立的条件。

同时用方程 ( 2 ) ( 3 ) (2)(3) (2)(3)来限制 X = x 1 + x 2 + x 3 X=x_1+x_2+x_3 X=x1+x2+x3,可以得到:

x 1 x_1 x1 5 5 5 7 7 7的倍数;

x 2 x_2 x2 3 3 3 7 7 7的倍数;

x 3 x_3 x3 3 3 3 5 5 5的倍数.

那么,如果我们分别找到满足这些条件的一组 x 1 , x 2 , x 3 x_1,x_2,x_3 x1,x2,x3,由上面的推导可知, X = x 1 + x 2 + x 3 X=x_1+x_2+x_3 X=x1+x2+x3就是方程组 ( 1 ) ( 2 ) ( 3 ) (1)(2)(3) (1)(2)(3)的一个解。

这时利用乘法逆元,有:

x ⋅ i n v ( x , p ) ≡ 1 ( m o d   p ) x·inv(x,p) \equiv 1 (mod\ p) xinv(x,p)1(mod p)

其中 i n v ( x , p ) inv(x,p) inv(x,p) x x x在模 p p p意义下的乘法逆元。

代入 x = 5 ∗ 7 = 35 , x=5*7=35, x=57=35,得:

35 ∗ i n v ( 35 , 3 ) ≡ 1 ( m o d   3 ) 35*inv(35,3) \equiv 1(mod\ 3) 35inv(35,3)1(mod 3)

等式两边同时乘以方程 ( 1 ) (1) (1)的余数 2 2 2,得:

35 ∗ i n v ( 35 , 3 ) ∗ 2 ≡ 2 ( m o d   3 ) 35*inv(35,3)*2\equiv2(mod\ 3) 35inv(35,3)22(mod 3).

x 1 = 35 ∗ i n v ( 35 , 3 ) ∗ 2 x_1=35*inv(35,3)*2 x1=35inv(35,3)2即可, x 2 , x 3 x_2,x_3 x2,x3可用类似方法求出。

我们就取得了一个 X = x 1 + x 2 + x 3 X=x_1+x_2+x_3 X=x1+x2+x3满足方程组 ( 1 ) ( 2 ) ( 3 ) . (1)(2)(3). (1)(2)(3).

然而这个 X X X不一定是满足方程组最小的 x x x,如果要找出最小的 x x x只需要把 X X X 3 ∗ 5 ∗ 7 = 105 3*5*7=105 357=105取余即可。

经过这个例子,我们可以总结出更一般的求解算法

对于同余方程组

x ≡ b 1 ( m o d   a 1 ) x\equiv b_1(mod\ a_1) xb1(mod a1)

x ≡ b 2 ( m o d   a 2 ) x\equiv b_2(mod\ a_2) xb2(mod a2)

. . . ... ...

x ≡ b n ( m o d   a n ) x\equiv b_n(mod\ a_n) xbn(mod an)

其中 a 1 , a 2 , . . . , a n a_1,a_2,...,a_n a1,a2,...,an互质。

P I = ∏ i = 1 n a i = a 1 a 2 . . . a n PI=\prod_{i=1}^{n}a_i=a_1a_2...a_n PI=i=1nai=a1a2...an,

那么可以取

x 1 = ( P I / a 1 ) ∗ i n v ( P I / a 1 , b 1 ) ∗ b 1 x_1=(PI/a_1)*inv(PI/a_1,b_1)*b_1 x1=(PI/a1)inv(PI/a1,b1)b1

x 2 = ( P I / a 2 ) ∗ i n v ( P I / a 2 , b 2 ) ∗ b 2 x_2=(PI/a_2)*inv(PI/a_2,b_2)*b_2 x2=(PI/a2)inv(PI/a2,b2)b2

. . . ... ...

x n = ( P I / a n ) ∗ i n v ( P I / a n , b n ) ∗ b n x_n=(PI/a_n)*inv(PI/a_n,b_n)*b_n xn=(PI/an)inv(PI/an,bn)bn

X = x 1 + x 2 + . . . + x n X=x_1+x_2+...+x_n X=x1+x2+...+xn

满足要求的最小 x m i n = X % P I x_{min}=X\%PI xmin=X%PI.

P1495 【模板】中国剩余定理(CRT)/曹冲养猪

C o d e : Code: Code:

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1E5+1;
typedef long long LL;
int n;
int a[MAXN],b[MAXN];
void exgcd(LL a,LL b,LL &x,LL &y)
{
	if(b == 0)
	{
		x = 1;
		y = 0;
		return;
	}
	exgcd(b,a%b,x,y);
	LL _x = x;
	x = y;
	y = _x-a/b*y;
}
LL inv(LL a,LL mod)
{
	LL x,y;
	exgcd(a,mod,x,y);
	return (x%mod+mod)%mod;
}
LL add(LL a,LL b,LL MOD)
{
	return (a%MOD+b%MOD)%MOD;
}
int main()
{
	scanf("%d",&n);
	LL PI = 1;
	for(int i=1;i<=n;i++)
	{
		scanf("%d%d",a+i,b+i);
		PI *= a[i];
	}
	LL sum = 0;
	for(int i=1;i<=n;i++)
	{
		sum = add(sum , b[i]*inv(PI/a[i],a[i])*(PI/a[i]) , PI);
	}
	printf("%lld",sum);
	return 0;
} 

3 扩展中国剩余定理

当方程组

x ≡ b 1 ( m o d   a 1 ) x\equiv b_1(mod\ a_1) xb1(mod a1)

x ≡ b 2 ( m o d   a 2 ) x\equiv b_2(mod\ a_2) xb2(mod a2)

. . . ... ...

x ≡ b n ( m o d   a n ) x\equiv b_n(mod\ a_n) xbn(mod an)

中的 a 1 , a 2 , . . . , a n a_1,a_2,...,a_n a1,a2,...,an不两两互质时,需要采用扩展中国剩余定理算法。

取出其中的两个方程:

x ≡ b 1 ( m o d   a 1 ) x\equiv b_1(mod\ a_1) xb1(mod a1)

x ≡ b 2 ( m o d   a 2 ) x\equiv b_2(mod\ a_2) xb2(mod a2)

由同余的意义,有

x = k 1 a 1 + b 1 x=k_1a_1+b_1 x=k1a1+b1

x = k 2 a 2 + b 2 x=k_2a_2+b_2 x=k2a2+b2

消去 x x x,得

k 1 a 1 + b 1 = k 2 a 2 + b 2 k_1a_1+b_1=k_2a_2+b_2 k1a1+b1=k2a2+b2

a 1 k 1 − k 2 a 2 = b 2 − b 1 a_1k_1-k_2a_2=b2-b1 a1k1k2a2=b2b1

为一个二元一次方程,可以用扩展欧几里得算法解出一个特解( ( 1.3 ) (1.3) (1.3)内容) ( k 1 , k 2 ) (k_1,k_2) (k1,k2)

( 1.4 ) (1.4) (1.4)结论,方程组有通解

x = x 1 + m ∗ ( b / g c d ( a , b ) ) x=x_1+m*(b/gcd(a,b)) x=x1+m(b/gcd(a,b))

y = y 1 − m ∗ ( a / g c d ( a , b ) ) , ( m ∈ Z ) . y=y_1-m*(a/gcd(a,b)),(m\in\mathbb{Z}). y=y1m(a/gcd(a,b)),(mZ).

x = ( k 1 + m r ) a 1 + b 1 , x=(k_1+mr)a_1+b_1, x=(k1+mr)a1+b1,其中 r = a 2 / g c d ( a 1 , a 2 ) r=a_2/gcd(a_1,a_2) r=a2/gcd(a1,a2)

所以

x = k 1 a 1 + m r a 1 + b 1 x=k_1a_1+mra_1+b_1 x=k1a1+mra1+b1

x = k 1 a 1 + m l c m ( a 1 , a 2 ) + b 1 x=k_1a_1+mlcm(a_1,a_2)+b_1 x=k1a1+mlcm(a1,a2)+b1

方程两边同模 l c m ( a 1 , a 2 ) lcm(a_1,a_2) lcm(a1,a2)

x ≡ k 1 a 1 + b 1 ( m o d   l c m ( a 1 , a 2 ) ) x\equiv k_1a_1+b_1(mod\ lcm(a_1,a_2)) xk1a1+b1(mod lcm(a1,a2))

这样,两个方程就合并成了一个方程,求解最后一个方程的最小正整数解即可。

P4777 【模板】扩展中国剩余定理(EXCRT)

C o d e : Code: Code:

#include<cstdio>
#include<cctype>
typedef __int128 LL;
const int MAXN = 1E5+1;
int n;
LL ai[MAXN],bi[MAXN];
inline void read(__int128 &X)
{
	X = 0;
	int w=0; char ch=0;
	while(!isdigit(ch)) {w|=ch=='-';ch=getchar();}
	while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
	if (w) X = -X;
}
void print(LL x)
{
	if (!x) return ;
	if (x < 0) putchar('-'),x = -x;
	print(x / 10);
	putchar(x % 10 + '0');
}
LL gcd(LL a,LL b)
{
	return !b?a:gcd(b,a%b);
}
LL exgcd(LL a,LL b,LL &x,LL &y)
{
	if(b == 0)
	{
		x = 1;
		y = 0;
		return a;
	}
	LL r = exgcd(b,a%b,x,y);
	LL x_ = x;
	x = y;
	y = x_-a/b*y;
	return r;
}
LL lcm(LL a,LL b)
{
	return a*b/gcd(a,b);
}
LL solve(LL a,LL b,LL c)
{
	LL x,y;
	exgcd(a,b,x,y);
	LL x1 = c/gcd(a,b)*x;
	LL mod = b/gcd(a,b);
	return (x1%mod+mod)%mod;
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		read(ai[i]),read(bi[i]);
	for(int i=1;i<n;i++)
	{
		LL a1 = ai[i],a2 = ai[i+1];
		LL b1 = bi[i],b2 = bi[i+1];
		LL k1 = solve(a1,a2,b2-b1);
		ai[i+1] = lcm(a1,a2);
		bi[i+1] = k1*a1+b1;
	}
	print(bi[n]);
	return 0;
}

本博客为自己学习中的理解,如有错误还请指出。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值