同余问题学习笔记
——by sunzz3183
扩展欧几里得(exgcd)
命题
对于两个正整数 a , b a,b a,b,存在两个整数 x , y x,y x,y 使得
a x + b y = g c d ( a , b ) ax+by=gcd(a,b) ax+by=gcd(a,b)
证明
在欧几里得算法的最后一步,即 b = 0 b=0 b=0 时,显然 x = 1 , y = 0 x=1,y=0 x=1,y=0,使得 a × 1 + 0 × 0 = g c d ( a , 0 ) a\times 1+0\times 0=gcd(a,0) a×1+0×0=gcd(a,0)。
若 b > 0 b>0 b>0 ,则, g c d ( a , b ) = g c d ( b , a m o d b ) gcd(a,b)=gcd(b,a \bmod b) gcd(a,b)=gcd(b,amodb)。假设存在一对整数 x , y x,y x,y,满足
b x + ( a m o d b ) y = g c d ( b , a m o d b ) bx+(a \bmod b)y=gcd(b,a \bmod b) bx+(amodb)y=gcd(b,amodb)
因为
b x + ( a m o d b ) y = b x + ( a − b ⌊ a b ⌋ ) y = a y + b ( x − ⌊ a b ⌋ y ) bx+(a \bmod b)y=bx+(a-b\left \lfloor \frac{a}{b} \right \rfloor )y=ay+b(x-\left \lfloor \frac{a}{b} \right \rfloor y) bx+(amodb)y=bx+(a−b⌊ba⌋)y=ay+b(x−⌊ba⌋y)
所以令 x ′ = y , y ′ = x − ⌊ a b ⌋ y x^{\prime}=y,y^{\prime}=x-\left \lfloor \frac{a}{b} \right \rfloor y x′=y,y′=x−⌊ba⌋y,就得到了 a x ′ + b y ′ = g c d ( a , b ) ax^{\prime}+by^{\prime}=gcd(a,b) ax′+by′=gcd(a,b)
证毕
代码
inline int exgcd(int a,int b,int &x,int &y){
if(!b){x=1;y=0;return a;}
int d=exgcd(b,a%b,y,x);
y-=(a/b)*x;
return d;
}
通式
则对于任意一个
a x 0 + b y 0 = c ax_0+by_0=c ax0+by0=c
当 g c d ( a , b ) ∣ c gcd(a,b)|c gcd(a,b)∣c 时,等式成立。
则此时
x 0 = x c gcd ( a , b ) , y 0 = y c gcd ( a , b ) x_0=x\frac{c}{\gcd (a,b)} ,y_0=y\frac{c}{\gcd (a,b)} x0=xgcd(a,b)c,y0=ygcd(a,b)c
通解
设二元一次不定方程
a x + b y = c ax+by=c ax+by=c
有一组整数解 x = x 0 , y = y 0 x=x_0,y=y_0 x=x0,y=y0,则一切整数解可以表示成
x = x 0 − b t gcd ( a , b ) , y = y 0 + a t gcd ( a , b ) x=x_0-\frac{bt}{\gcd (a,b)},y=y0+\frac{at}{\gcd (a,b)} x=x0−gcd(a,b)bt,y=y0+gcd(a,b)at
其中 $t=0,\pm 1,\pm 2,\pm 3,\cdots $
证明
既然 x 0 , y 0 x0,y0 x0,y0 为整数解,当然满足 a x 0 + b y 0 = c ax_0+by_0=c ax0+by0=c,因此
a ( x 0 − b t gcd ( a , b ) ) + b ( y 0 + a t gcd ( a , b ) ) = a x 0 + b y 0 = c a(x_0-\frac{bt}{\gcd (a,b)})+b(y0+\frac{at}{\gcd (a,b)})= ax_0+by_0=c a(x0−gcd(a,b)bt)+b(y0+gcd(a,b)at)=ax0+by0=c
设 x ′ , y ′ x^{\prime },y^{\prime } x′,y′ 为任意一组整数解,则有 a x ′ + b y ′ = c ax^{\prime }+by^{\prime }=c ax′+by′=c,减去 a x 0 + b y 0 = c ax_0+by_0=c ax0+by0=c,即得
a ( x ′ − x 0 ) + b ( y ′ − y 0 ) = 0 a(x^{\prime }-x_0)+b(y^{\prime }-y_0)=0 a(x′−x0)+b(y′−y0)=0
a ( x ′ − x 0 ) = − b ( y ′ − y 0 ) a(x^{\prime }-x_0)=-b(y^{\prime }-y_0) a(x′−x0)=−b(y′−y0)
所以我们得到
a ∣ ( y ′ − y 0 ) a|(y^{\prime }-y_0) a∣(y′−y0)
即
y ′ = y 0 + a t y^{\prime }=y_0+at y′=y0+at
将
y ′ = y 0 + a t y^{\prime }=y_0+at y′=y0+at
代入
a ( x ′ − x 0 ) + b ( y ′ − y 0 ) = 0 a(x^{\prime }-x_0)+b(y^{\prime }-y_0)=0 a(x′−x0)+b(y′−y0)=0
即得
x ′ = x 0 − b t x^{\prime }=x_0-bt x′=x0−bt
因此
x ′ , y ′ x^{\prime },y^{\prime } x′,y′
可表示成 x ′ = x 0 − b t gcd ( a , b ) , y ′ = y 0 + a t gcd ( a , b ) x^{\prime }=x_0-\frac{bt}{\gcd (a,b)},y^{\prime }=y0+\frac{at}{\gcd (a,b)} x′=x0−gcd(a,b)bt,y′=y0+gcd(a,b)at 的形式
所以
x = x 0 − b t gcd ( a , b ) , y = y 0 + a t gcd ( a , b ) x=x_0-\frac{bt}{\gcd (a,b)},y=y0+\frac{at}{\gcd (a,b)} x=x0−gcd(a,b)bt,y=y0+gcd(a,b)at
为 a x + b y = c ax+by=c ax+by=c 的一切整数解
证毕
中国剩余定理(CRT)
命题
已知同余式组
{ x ≡ b 1 ( m o d m 1 ) , x ≡ b 2 ( m o d m 2 ) , ⋯ , x ≡ b n ( m o d m n ) \left\{\begin{matrix} x\equiv b_1\pmod{m_1} , \\x\equiv b_2\pmod{m_2}, \\\cdots , \\x\equiv b_n\pmod{m_n} \end{matrix}\right. ⎩ ⎨ ⎧x≡b1(modm1),x≡b2(modm2),⋯,x≡bn(modmn)
其中 b ∈ N , m ∈ N ∗ , m i ⊥ m j b\in \mathbb{N} ,m\in \mathbb{N^* } ,m_i \perp m_j b∈N,m∈N∗,mi⊥mj
求 x x x
求法
令
M = ∏ i = 1 n m i = m 1 M 1 = m 2 M 2 = ⋯ = m n M n M=\prod_{i=1}^{n}m_i=m_1M_1=m_2M_2=\cdots=m_nM_n M=i=1∏nmi=m1M1=m2M2=⋯=mnMn
则同时满足同余式组
{ x ≡ b 1 ( m o d m 1 ) , x ≡ b 2 ( m o d m 2 ) , ⋯ , x ≡ b n ( m o d m n ) \left\{\begin{matrix} x\equiv b_1\pmod{m_1} , \\x\equiv b_2\pmod{m_2}, \\\cdots , \\x\equiv b_n\pmod{m_n} \end{matrix}\right. ⎩ ⎨ ⎧x≡b1(modm1),x≡b2(modm2),⋯,x≡bn(modmn)
的正整数解是
x ≡ ∑ i = 1 n b i M i ′ M i ( m o d M ) x\equiv \sum_{i=1}^{n}b_iM_i^{\prime}M_i \pmod{M} x≡i=1∑nbiMi′Mi(modM)
这里的 M i ′ M_i^{\prime} Mi′ 是满足同余式
M i ′ M i ≡ 1 ( m o d m ) M_i^{\prime}M_i\equiv 1\pmod{m} Mi′Mi≡1(modm)
的正整数解
证明
因为 m i ⊥ m j , M i = M m i m_i \perp m_j,M_i=\frac{M}{m_i} mi⊥mj,Mi=miM,所以 m i ⊥ M i m_i \perp M_i mi⊥Mi,所以
g c d ( m i , M i ) = g c d ( m j , M j ) = 1 gcd(m_i,M_i)=gcd(m_j,M_j)=1 gcd(mi,Mi)=gcd(mj,Mj)=1
由扩展欧几里得可得,存在两个整数 M i ′ , n i M_i^{\prime},n_i Mi′,ni,使得
M i ′ M i + m i + n i = 1 M_i^{\prime}M_i+m_i+n_i=1 Mi′Mi+mi+ni=1
所以存在一个 M i ′ M_i^{\prime} Mi′,使得
M i ′ M i ≡ 1 ( m o d m i ) M_i^{\prime}M_i \equiv 1 \pmod{m_i} Mi′Mi≡1(modmi)
又由当 i ≠ j i\ne j i=j时,则由 m i ⊥ m j , M j = M m j m_i \perp m_j,M_j=\frac{M}{m_j} mi⊥mj,Mj=mjM 得到 m i ∣ M j m_i|M_j mi∣Mj,所以
b j M j ′ M j ≡ 0 ( m o d m i ) b_jM_j^{\prime}M_j\equiv 0 \pmod{m_i} bjMj′Mj≡0(modmi)
所以
∑ i = 1 n b i M i ′ M i ≡ b i M i ′ M i ≡ b i ( m o d m i ) \sum_{i=1}^{n}b_iM_i^{\prime}M_i \equiv b_iM_i^{\prime}M_i\equiv b_i \pmod{m_i} i=1∑nbiMi′Mi≡biMi′Mi≡bi(modmi)
设 y y y 为同余式组的一个整数解,则得
{ x ≡ y ( m o d m 1 ) , x ≡ y ( m o d m 2 ) , ⋯ , x ≡ y ( m o d m n ) \left\{\begin{matrix} x\equiv y\pmod{m_1} , \\x\equiv y\pmod{m_2}, \\\cdots , \\x\equiv y\pmod{m_n} \end{matrix}\right. ⎩ ⎨ ⎧x≡y(modm1),x≡y(modm2),⋯,x≡y(modmn)
也就是
m 1 ∣ ( x − y ) , m 2 ∣ ( x − y ) , ⋯ , m n ∣ ( x − y ) \begin{matrix} m_1|(x-y), \\m_2|(x-y), \\\cdots , \\m_n|(x-y) \end{matrix} m1∣(x−y),m2∣(x−y),⋯,mn∣(x−y)
又因为 m i ⊥ m j m_i \perp m_j mi⊥mj,所以有 M ∣ ( x − y ) M|(x-y) M∣(x−y),也就是
x ≡ y ( m o d M ) x\equiv y \pmod{M} x≡y(modM)
所以
x ≡ ∑ i = 1 n b i M i ′ M i ( m o d M ) x\equiv \sum_{i=1}^{n}b_iM_i^{\prime}M_i \pmod{M} x≡i=1∑nbiMi′Mi(modM)
是满足同余式组的唯一正整数解
证毕
代码
inline int exgcd(int a,int b,int &x,int &y){
if(!b){x=1;y=0;return a;}
int d=exgcd(b,a%b,y,x);
y-=(a/b)*x;
return d;
}
int CRT(int A[],int B[],int k){
int x,y,a=0,m,n=1;
for(int i=1;i<=k;i++)n*=A[i];
for(int i=1;i<=k;i++){
m=n/A[i];
exgcd(A[i],m,x,y);
(a+=y*m*B[i])%=n;
}
return (a+n)%n;
}
扩展中国剩余定理(exCRT)
命题
已知同余式组
{ X ≡ b 1 ( m o d m 1 ) , X ≡ b 2 ( m o d m 2 ) , ⋯ , X ≡ b n ( m o d m n ) \left\{\begin{matrix} X\equiv b_1\pmod{m_1} , \\X\equiv b_2\pmod{m_2}, \\\cdots , \\X\equiv b_n\pmod{m_n} \end{matrix}\right. ⎩ ⎨ ⎧X≡b1(modm1),X≡b2(modm2),⋯,X≡bn(modmn)
其中 b ∈ N , m ∈ N ∗ b\in \mathbb{N} ,m\in \mathbb{N^* } b∈N,m∈N∗
求 X X X
与 C R T CRT CRT 不同的是,这个 m i , m j m_i,m_j mi,mj,不一定两两互质。
求法
(建议配合代码食用)
考虑合并
{
X
≡
b
1
(
m
o
d
m
1
)
,
X
≡
b
2
(
m
o
d
m
2
)
\left\{\begin{matrix} X\equiv b_1\pmod{m_1} , \\X\equiv b_2\pmod{m_2} \end{matrix}\right.
{X≡b1(modm1),X≡b2(modm2)
可以写成
{ X = b 1 + m 1 x , X = b 2 + m 2 y \left\{\begin{matrix} X=b_1+m_1x , \\X=b_2+m_2y \end{matrix}\right. {X=b1+m1x,X=b2+m2y
所以
b 1 + m 1 x = b 2 + m 2 y b_1+m_1x=b_2+m_2y b1+m1x=b2+m2y
整理,得
m 1 x + m 2 ( − y ) = b 2 − b 1 m_1x+m_2(-y)=b_2-b_1 m1x+m2(−y)=b2−b1
通过 e x g c d exgcd exgcd 可以得到一组解 x 0 , y 0 x_0,y_0 x0,y0
所以
m 1 x 0 b 2 − b 1 gcd ( m 1 , m 2 ) + m 2 y 0 b 2 − b 1 gcd ( m 1 , m 2 ) = gcd ( m 1 , m 2 ) b 2 − b 1 gcd ( m 1 , m 2 ) = b 2 − b 1 m_1x_0\frac{b_2-b_1}{\gcd(m_1,m_2)}+m_2y_0\frac{b_2-b_1}{\gcd(m_1,m_2)}=\gcd(m_1,m_2)\frac{b_2-b_1}{\gcd(m_1,m_2)}=b_2-b_1 m1x0gcd(m1,m2)b2−b1+m2y0gcd(m1,m2)b2−b1=gcd(m1,m2)gcd(m1,m2)b2−b1=b2−b1
因为 X = m 1 x + b 1 X=m_1x+b_1 X=m1x+b1,现在要最小化 X X X,也就是最小化 x x x,即最小化 x = x 0 b 2 − b 1 gcd ( m 1 , m 2 ) x=x_0\frac{b_2-b_1}{\gcd(m_1,m_2)} x=x0gcd(m1,m2)b2−b1
我们假设 b 2 , m 2 b_2,m_2 b2,m2,为已经算出的前 k k k 对数的答案
于是就可以将这两个同余方程合并为
X ≡ m 1 x + b 1 ( m o d l c m ( m 1 , m 2 ) ) X\equiv m_1x+b_1 \pmod {lcm(m_1,m_2)} X≡m1x+b1(modlcm(m1,m2))
代码
inline int exgcd(int a,int b,int &x,int &y){
if(!b){x=1;y=0;return a;}
int d=exgcd(b,a%b,y,x);
y-=(a/b)*x;
return d;
}
int exCRT(int *A,int *B,int k){
int x,y,a=A[1],ans=B[1];
for(int i=2;i<=k;i++){
int b=A[i],c=((B[i]-ans)%b+b)%b,d=exgcd(a,b,x,y);
if(c%d)return -1;
x=(__int128)x*(__int128)c/(__int128)d%(b/d);
ans+=a*x;
a=a/d*b;
ans=(ans%a+a)%a;
}
return (ans%a+a)%a;
}