class="markdown_views prism-dracula">
参考博客
Acdreamer
一次同余方程
a ∗ x ≡ b ( m o d n ) " role="presentation">a ∗ x ≡ b ( m o d n ) a ∗ x ≡ b ( m o d n )
分情况讨论
若有( a , n ) = 1 " role="presentation">( a , n ) = 1 ( a , n ) = 1 ,根据 欧几里得扩展 ,存在 l,m使得a ∗ l + n ∗ m = 1 " role="presentation">a ∗ l + n ∗ m = 1 a ∗ l + n ∗ m = 1 ,等式两边同时模n,得 a ∗ l ≡ 1 ( m o d n ) " role="presentation">a ∗ l ≡ 1 ( m o d n ) a ∗ l ≡ 1 ( m o d n ) ,对于 a ∗ x ≡ b ( m o d n ) " role="presentation">a ∗ x ≡ b ( m o d n ) a ∗ x ≡ b ( m o d n ) a ∗ l ∗ x ≡ b ∗ l ( m o d n ) " role="presentation">a ∗ l ∗ x ≡ b ∗ l ( m o d n ) a ∗ l ∗ x ≡ b ∗ l ( m o d n ) x ≡ b ∗ l ( m o d n ) " role="presentation">x ≡ b ∗ l ( m o d n ) x ≡ b ∗ l ( m o d n )
若有 ( a , n ) = d " role="presentation">( a , n ) = d ( a , n ) = d , 对于 a ∗ x ≡ b ( m o d n ) " role="presentation">a ∗ x ≡ b ( m o d n ) a ∗ x ≡ b ( m o d n )
移项
a ∗ x − b ≡ 0 ( m o d n ) " role="presentation">a ∗ x − b ≡ 0 ( m o d n ) a ∗ x − b ≡ 0 ( m o d n )
即
n | ( a ∗ x − b ) " role="presentation">n | ( a ∗ x − b ) n | ( a ∗ x − b )
已知
d | a , d | n " role="presentation">d | a , d | n d | a , d | n
于是
d | b " role="presentation">d | b d | b
所以同余方程有解的条件是
d | b " role="presentation">d | b d | b
令
a 1 = a / d , b 1 = b / d , n 1 = n / d " role="presentation">a 1 = a / d , b 1 = b / d , n 1 = n / d a 1 = a / d , b 1 = b / d , n 1 = n / d
则有
n 1 | ( a 1 ∗ x − b 1 ) " role="presentation">n 1 | ( a 1 ∗ x − b 1 ) n 1 | ( a 1 ∗ x − b 1 )
即为
a 1 ∗ x ≡ b 1 ( m o d n 1 ) 且 ( a 1 , n 1 ) = 1 " role="presentation">a 1 ∗ x ≡ b 1 ( m o d n 1 ) 且 ( a 1 , n 1 ) = 1 a 1 ∗ x ≡ b 1 ( m o d n 1 ) 且 ( a 1 , n 1 ) = 1
就变成情况1,可以解出此时的
x ≡ b 1 ∗ l ( m o d n 1 ) " role="presentation">x ≡ b 1 ∗ l ( m o d n 1 ) x ≡ b 1 ∗ l ( m o d n 1 )
即
x = b 1 ∗ l + n 1 ∗ t " role="presentation">x = b 1 ∗ l + n 1 ∗ t x = b 1 ∗ l + n 1 ∗ t t的取值范围 为(0,d-1)
中国剩余定理
解线性同余方程,运用
拉格朗日插值法 ,得孙子定理
模板
int m [maxn];
int China(int a[],int n,int b[])//其中a[]是模数,b[] 是余数
{
int M = 1 ;
for (int i = 0 ;i < n;++i)
M *= a[i];
int ans = 0 ;
for (int i = 0 ;i < n;++i)
{
int Mi = M/a[i];
LL x ,y ;
ex_gcd(Mi,a[i],x ,y );
ans += b[i] * x *Mi ;
}
ans = (ans%M + M) %M ;
return ans;
}
扩展
合并两个模数
假设
y = a 1 ( m o d m 1 ) " role="presentation">y =