2024.4.29 【锦水汤汤,与君长诀!】
Monday 三月二十一
数论专题
同余
除法定理
对于任何整数a,和正整数m,存在唯一整数q,r,使得满足 0 ≤ r < m , a = q m + r 0\le r < m,a = qm+r 0≤r<m,a=qm+r
其中
q
=
⌊
a
m
⌋
q = \lfloor \frac{a}{m}\rfloor
q=⌊ma⌋
为商,
r
=
a
m
o
d
m
r = a \ mod \ m
r=a mod m为余数
余数
将a mod m记作余数
同余
如果
a
m
o
d
m
=
b
m
o
d
m
a \mod\ m = b \mod\ m
amod m=bmod m,那么称a,b在模m意义下同余,记作
a
≡
b
(
m
o
d
m
)
a \equiv b \pmod m
a≡b(modm)
且有
(
a
,
m
)
=
(
b
,
m
)
(a,m) = (b,m)
(a,m)=(b,m)
若 d ∣ m d|m d∣m,有 a ≡ b ( m o d d ) a \equiv b \pmod d a≡b(modd)
同余是 等价关系,即同余具有
自反性:
a
≡
a
(
m
o
d
m
)
a\equiv a\pmod m
a≡a(modm)。
对称性:若
a
≡
b
(
m
o
d
m
)
a\equiv b\pmod m
a≡b(modm),则
b
≡
a
(
m
o
d
m
)
b\equiv a\pmod m
b≡a(modm)。
传递性:若
a
≡
b
(
m
o
d
m
)
,
b
≡
c
(
m
o
d
m
)
a\equiv b\pmod m,b\equiv c\pmod m
a≡b(modm),b≡c(modm),则
a
≡
c
(
m
o
d
m
)
a\equiv c\pmod m
a≡c(modm)。
线性运算:若
a
,
b
,
c
,
d
∈
Z
,
m
∈
N
∗
,
a
≡
a,b,c,d\in\mathbf{Z},m\in\mathbf{N}^*,a\equiv
a,b,c,d∈Z,m∈N∗,a≡
b
(
m
o
d
m
)
,
c
≡
d
(
m
o
d
m
)
b\pmod m,c\equiv d\pmod m
b(modm),c≡d(modm) 则有:
a
±
c
≡
b
±
d
(
m
o
d
m
)
a\pm c\equiv b\pm d\pmod m
a±c≡b±d(modm)。
a
×
c
≡
b
×
d
(
m
o
d
m
)
a\times c\equiv b\times d\pmod m
a×c≡b×d(modm)。
设
f
(
x
)
=
∑
i
=
0
n
a
i
x
i
f(x)=\sum_{i=0}^n a_ix^i
f(x)=∑i=0naixi 和
g
(
x
)
=
∑
i
=
0
n
b
i
x
i
g(x)=\sum_{i=0}^n b_ix^i
g(x)=∑i=0nbixi 是两个整系数多项式,
m
∈
N
∗
m\in\mathbf{N}^*
m∈N∗,则对任意整数 x 均有
f
(
x
)
≡
g
(
x
)
(
m
o
d
m
)
f(x)\equiv g(x)\pmod m
f(x)≡g(x)(modm)。进而若
a
i
≡
b
i
(
m
o
d
m
)
,
0
≤
i
≤
n
a_i\equiv b_i\pmod m,~0\leq i\leq n
ai≡bi(modm), 0≤i≤n,那么若
s
≡
t
(
m
o
d
m
)
s\equiv t\pmod m
s≡t(modm),则
f
(
s
)
≡
g
(
t
)
(
m
o
d
m
)
f(s)\equiv g(t)\pmod m
f(s)≡g(t)(modm)。
若
a
,
b
∈
Z
,
k
,
m
∈
N
∗
,
a
≡
b
(
m
o
d
m
)
a,b\in\mathbf{Z},k,m\in\mathbf{N}^*,a\equiv b\pmod m
a,b∈Z,k,m∈N∗,a≡b(modm), 则
a
k
≡
b
k
(
m
o
d
m
k
)
ak\equiv bk\pmod{mk}
ak≡bk(modmk)。
若
a
,
b
∈
Z
,
d
,
m
∈
N
∗
,
d
∣
a
,
d
∣
b
,
d
∣
m
a,b\in\mathbf{Z},d,m\in\mathbf{N}^*,d\mid a,d\mid b,d\mid m
a,b∈Z,d,m∈N∗,d∣a,d∣b,d∣m,则当
a
≡
b
(
m
o
d
m
)
a\equiv b\pmod m
a≡b(modm) 成立时,有
a d ≡ b d ( m o d m d ) \dfrac{a}{d}\equiv\dfrac{b}{d}\left(\bmod\;{\dfrac{m}{d}}\right) da≡db(moddm)。
若
a
,
b
∈
Z
,
d
,
m
∈
N
∗
,
d
∣
m
a,b\in\mathbf{Z},d,m\in\mathbf{N}^*,d\mid m
a,b∈Z,d,m∈N∗,d∣m,则当
a
≡
b
(
m
o
d
m
)
a\equiv b\pmod m
a≡b(modm) 成立时,有
a
≡
b
(
m
o
d
d
)
a\equiv b\pmod d
a≡b(modd)。
若
a
,
b
∈
Z
,
d
,
m
∈
N
∗
a,b\in\mathbf{Z},d,m\in\mathbf{N}^*
a,b∈Z,d,m∈N∗,则当
a
≡
b
(
m
o
d
m
)
a\equiv b\pmod m
a≡b(modm) 成立时,有
(
a
,
m
)
=
(
b
,
m
)
(a,m)=(b,m)
(a,m)=(b,m)。若 d 能整除 m 及 a,b 中的一个,则 d 必定能整除 a,b 中的另一个。
剩余系
剩余系是指模正整数 𝑛 的余数所组成的集合。
如果一个剩余系中包含了这个正整数 𝑛 所有可能的余数(一般地,对于任意正整数 𝑛,有 𝑛 个余数:0,1,2,…,𝑛−1),那么就被称为是模 𝑛 的一个完全剩余系,记作 Z n Z_n Zn;而简化剩余系就是完全剩余系中与 𝑛 互素的数,记作 Z n ∗ Z_n^∗ Zn∗。
𝑍_𝑛 里面的每一个元素代表所有模 𝑛 意义下与它同余的整数。例如 𝑛=5 时,𝑍_5 的元素3 实际上代表了 3,8,13,18,….,5𝑘+3(𝑘∈𝑁) 这些模 5 余 3 的数。我们把满足同余关系的所有整数看作一个同余等价类。
自然地,在 𝑍_𝑛中的加法,减法,乘法,结果全部要在模 𝑛 意义下面了例如在 Z 5 Z_5 Z5中,3+2=0 , 3×2=1 。
素数
oi.wiki!
是啥咱就不多说了
上板子
埃氏筛法
1 #define maxn 1000000
2 bool isPrime[maxn+1];
3 int minFactor[maxn+1]; //记录每个数的最小素因数的数组
4
5 void eratos(int n){
6 int i,j;
7 isPrime[0] = isPrime[1] = false;
8 minFactor[0] = minFactor[1] = -1;
9 for(i = 2;i <= n; ++i) {
10 isPrime[i] = true;
11 minFactor[i] = i; //初始化,表示还未找到最小的素因数
12 }
欧拉筛法
1 void Euler_sieve(int n){
2 memset(isprime,true,sizeof(isprime));
3 prime[0]=0; //记录当前素数个数
4 for(int i=2;i<=n;i++){
5 if (isprime[i])prime[++prime[0]]=i;//把素数保存到素数表prime中,并更新素数个数
6 for(int j=1;j<=prime[0] && i*prime[j]<=n;j++){
7 isprime[i*prime[j]]=false;//筛除i*prime[j]
8 if (i % prime[j]==0) break;
9 //当i中含有素因子prime[j]时中断循环,确保每个数只被它的最小素因子筛除
10 }
11 }
12 }
公因数,公倍数
oi.wiki!
辗转相除法更相减损法好像更高级一点
int gcd(int a,int b){return (b == 0) ? a : gcd(b, a % b);}
多个数的最大公约数
显然答案一定是每个数的约数,那么也一定是每相邻两个数的约数。我们采用归纳法,可以证明,每次取出两个数求出答案后再放回去,不会对所需要的答案造成影响。
最小公倍数
高精度计算
1 int gcd(int m,int n){
2 if (m == n) return m;
3 if (m < n) return gcd(n,m);
4 if (m & 1 == 0) 5 return (n & 1 == 0)? 2*gcd(m>>1,n>>1):gcd(m>>1,n);
6 return (n & 1 == 0)? gcd(m,n>>1): gcd(n,m-n);
7 }
//代码中运算符需重载
最小公倍数
1 ans=1;
2 for(int i=1;i<=n;i++){
3 scanf("%d",&a[i]);
4 ans=ans*a[i]/gcd(ans,a[i]);
5 }
6 printf("%d",ans);
拓展欧几里得定理
裴蜀定理 (Bézout)
对任意a,b,关于未知数x,y的线性丢番图方程: a x + b y = c ax+by=c ax+by=c(裴蜀等式)
方程有整数解当且仅当c是gcd(a,b)的倍数。
裴蜀等式有解时必有无穷多个解。
证明:
p
=
g
c
d
(
a
,
b
)
a
=
a
′
∗
p
b
=
b
′
∗
p
g
d
c
(
a
′
,
b
′
)
=
1
c
=
a
x
+
b
y
=
p
∗
(
a
′
x
+
b
′
y
)
p = gcd(a,b) \\ a = a'*p\\ b = b'*p\\ gdc(a',b') = 1\\ c = ax+by = p*(a'x+b'y)
p=gcd(a,b)a=a′∗pb=b′∗pgdc(a′,b′)=1c=ax+by=p∗(a′x+b′y)
代码:
1 void Extened_Euclid(int a,int b,int &d,int &x,int &y){
2 if (b==0){d = a;x = c/a;y = 0;}
3 else{
4 int x1,x2;
5 Extened_Euclid(b,a%b,d,x1,x2);
6 x = y1;
7 y = x1-a/b*y1;
8 }
9 }
推论:𝑎,𝑏 互素等价于 𝑎𝑥+𝑏𝑦=1 有解。
拓展欧几里得算法
根据欧几里得算法,可得:
a
x
+
b
y
=
g
c
d
(
a
,
b
)
=
g
d
c
(
b
,
a
m
o
d
b
)
=
b
x
′
+
(
a
m
o
d
b
)
y
′
ax+by = gcd(a,b) = gdc(b,a\ mod\ b) = bx'+(a\ mod\ b)y'
ax+by=gcd(a,b)=gdc(b,a mod b)=bx′+(a mod b)y′
其中 a m o d b a\ mod\ b a mod b为 a − ⌊ a b ⌋ a- \lfloor \frac{a}{b} \rfloor a−⌊ba⌋,代入上式后,可得:
可以得出𝑥,𝑦和𝑥’,𝑦’ 的关系
x
=
y
′
,
y
=
x
′
−
⌊
a
b
⌋
y
′
x = y',y = x'- \lfloor \frac{a}{b} \rfloor y'
x=y′,y=x′−⌊ba⌋y′
边界情况分析:𝑎𝑥’+𝑏𝑦’=𝑑(𝑑=gcd(𝑎,𝑏)),当 𝑏=0 时,𝑎 为 gcd(𝑎,𝑏),当且仅当 𝑥’=1 时等式成立。𝑦’ 可以为任何值,为方便起见,设 𝑦’=0 。
根据 𝑥=𝑦’,𝑦=𝑥’−⌊𝑎/𝑏⌋∗𝑦’,可以倒推出 𝑥 和 𝑦 的多组解。
1 int extend_gcd(int a, int b, int &x, int &y) {
2 if (b == 0) {
3 x = 1; y = 0;
4 return a;
5 }
6 else {
7 int ret = extend_gcd(b, a % b, y, x);
8 y -= x * (a / b);
9 return ret;
10 }
11 }
值域分析
a x + b y = gcd ( a , b ) ax+by=\gcd(a,b) ax+by=gcd(a,b) 的解有无数个,显然其中有的解会爆 long long。
万幸的是,若 b ≠ 0 b\not= 0 b=0,扩展欧几里得算法求出的可行解必有 ∣ x ∣ ≤ b , ∣ y ∣ ≤ a |x|\le b,|y|\le a ∣x∣≤b,∣y∣≤a。
欧拉函数
oi.wiki!
若gcd(a,b) = 1,则称a,b互素,记作
a
⊥
b
a\perp b
a⊥b
欧拉函数,记作 φ ( n ) \varphi (n) φ(n),表示[1,n]中与n互素数的个数
欧拉函数具有很多优异的性质,比如:若p是素数,则
φ
(
p
)
=
p
−
1
\varphi (p) = p-1
φ(p)=p−1
且,我们知道,欧拉函数是一个积性函数,所以,
φ
(
a
)
∗
φ
(
b
)
=
φ
(
a
∗
b
)
\varphi(a)*\varphi(b) = \varphi(a*b)
φ(a)∗φ(b)=φ(a∗b)
(积性函数:对于任意互质的整数a和b有性质f(ab)=f(a)f(b)的数论函数。完全积性函数:对于任意整数a和b有性质f(ab)=f(a)f(b)的数论函数。)
这为我们求解提供了便利
特别地,当 n 是奇数时 φ ( 2 n ) = φ ( n ) \varphi(2n) = \varphi(n) φ(2n)=φ(n)
并且 n = ∑ d ∣ n φ ( d ) n = \sum_{d \mid n}{\varphi(d)} n=∑d∣nφ(d)
素因数分解求解
1 int euler_phi(int n){
2 int res = n;
3 for(int i = 2; i * i <= n; i++) {
4 if(n % i == 0) {
5 res = res / i * (i - 1);
6 for (; n % i == 0; n /= i);
7 }
8 }
9 if (n != 1) res = res / n * (n - 1);
10 return res;
11 }
埃氏筛法求解
1 int euler[MAX_N];
2 void euler_phi2(){
3 for (int i = 0; i < MAX_N; i++) euler[i] = i;
4 for (int i = 2; i < MAX_N; i++) {
5 if (euler[i] == i) {
6 for (int j = i; j < MAX_N; j += i)
7 euler[j] = euler[j] / i * (i - 1);
8 }
9 }
10 }
欧拉定理
费马小定理
费马小定理
定义
若 p 为素数,
gcd
(
a
,
p
)
=
1
\gcd(a, p) = 1
gcd(a,p)=1,则
a
p
−
1
≡
1
(
m
o
d
p
)
a^{p - 1} \equiv 1 \pmod{p}
ap−1≡1(modp)。
另一个形式:对于任意整数 a,有 a p ≡ a ( m o d p ) a^p \equiv a \pmod{p} ap≡a(modp)。
一般情况下,在p是素数时,对任意整数a,都有
a
p
≡
a
(
m
o
d
p
)
a^p \equiv a \pmod{p}
ap≡a(modp)
若p为素数,a,p互素,则
a
b
m
o
d
p
=
a
b
m
o
d
p
m
o
d
p
a^b\ mod\ p = a^{b \ mod \ p}\mod p
ab mod p=ab mod pmodp
欧拉定理
定义
若
gcd
(
a
,
m
)
=
1
\gcd(a, m) = 1
gcd(a,m)=1,则
a
φ
(
m
)
≡
1
(
m
o
d
m
)
a^{\varphi(m)} \equiv 1 \pmod{m}
aφ(m)≡1(modm)。
证明
设 r 1 , r 2 , ⋯ , r φ ( m ) r_1, r_2, \cdots, r_{\varphi(m)} r1,r2,⋯,rφ(m) 为模 m 意义下的一个简化剩余系,则 a r 1 , a r 2 , ⋯ , a r φ ( m ) ar_1, ar_2, \cdots, ar_{\varphi(m)} ar1,ar2,⋯,arφ(m) 也为模 m 意义下的一个简化剩余系。所以 r 1 r 2 ⋯ r φ ( m ) ≡ a r 1 ⋅ a r 2 ⋯ a r φ ( m ) ≡ a φ ( m ) r 1 r 2 ⋯ r φ ( m ) ( m o d m ) r_1r_2 \cdots r_{\varphi(m)} \equiv ar_1 \cdot ar_2 \cdots ar_{\varphi(m)} \equiv a^{\varphi(m)}r_1r_2 \cdots r_{\varphi(m)} \pmod{m} r1r2⋯rφ(m)≡ar1⋅ar2⋯arφ(m)≡aφ(m)r1r2⋯rφ(m)(modm),可约去 r 1 r 2 ⋯ r φ ( m ) ,即得 a φ ( m ) ≡ 1 ( m o d m ) r_1r_2 \cdots r_{\varphi(m)},即得 a^{\varphi(m)} \equiv 1 \pmod{m} r1r2⋯rφ(m),即得aφ(m)≡1(modm)。
逆元
如果一个线性同余方程 a x ≡ 1 ( m o d b ) ax \equiv 1 \pmod b ax≡1(modb),则 x 称为 a m o d b a \bmod b amodb 的逆元,记作 a − 1 a^{-1} a−1。
模n意义下乘法的逆
在 Z n Z_n Zn中两元素a,b满足a*b = 1,我们称a,b互为模n意义下乘法的逆元
在模意义下,除一个数等于乘这个数的逆元。
剩余系中每一个元素都是一个同余等价类。
当a,m互素时,若有 a x ≡ 1 ( m o d m ) ax \equiv 1 \pmod m ax≡1(modm),称x是a关于模m的逆元,记作 a − 1 a^{-1} a−1,在[0,m]范围内,逆元唯一。
欧几里得方法求解
等价于解方程 a x + m y = 1 ax+my = 1 ax+my=1
1 int inverse(int a, int b) {
2 int x, y;
3 extend_gcd(a, b, x, y);
4 return x;
5 }
欧拉定理求解(快速幂法)
a
∗
a
φ
(
m
)
−
1
≡
1
(
m
o
d
m
)
a*a^{\varphi(m)-1}\equiv1 \pmod m
a∗aφ(m)−1≡1(modm)
若p为素
a
∗
a
m
−
2
≡
1
(
m
o
d
m
)
a*a^{m-2}\equiv1 \pmod m
a∗am−2≡1(modm)
证明
因为
a
x
≡
1
(
m
o
d
b
)
ax \equiv 1 \pmod b
ax≡1(modb);
所以 a x ≡ a b − 1 ( m o d b ) ax \equiv a^{b-1} \pmod b ax≡ab−1(modb)(根据 费马小定理);
所以 x ≡ a b − 2 ( m o d b ) x \equiv a^{b-2} \pmod b x≡ab−2(modb)。
然后我们就可以用快速幂来求了。
int qpow(long long a, int b) {
int ans = 1;
a = (a % p + p) % p;
for (; b; b >>= 1) {
if (b & 1) ans = (a * ans) % p;
a = (a * a) % p;
}
return ans;
}
线性方法
线性求逆元
求出
1
,
2
,
…
,
n
1,2,\dots,n
1,2,…,n 中每个数关于 p 的逆元。
如果对于每个数进行单次求解,以上两种方法就显得慢了,很有可能超时,所以下面来讲一下如何线性(O(n))求逆元。
首先,很显然的 1 − 1 ≡ 1 ( m o d p ) 1^{-1} \equiv 1 \pmod p 1−1≡1(modp);
inv[1] = 1;
for (int i = 2; i <= n; ++i) {
inv[i] = (long long)(p - p / i) * inv[p % i] % p;
}
线性求任意个
上面的方法只能求 1 到 n 的逆元,如果需要求任意给定 n 个数 ( 1 ≤ a i < p ) (1 \le a_i < p) (1≤ai<p)的逆元,就需要下面的方法:
首先计算 n 个数的前缀积,记为 s i s_i si,然后使用快速幂或扩展欧几里得法计算 s n s_n sn 的逆元,记为 s v n sv_n svn。
因为 s v n sv_n svn 是 n 个数的积的逆元,所以当我们把它乘上 a n a_n an 时,就会和 a n a_n an 的逆元抵消,于是就得到了 a 1 a_1 a1 到 a n − 1 a_{n-1} an−1 的积逆元,记为 s v n − 1 sv_{n-1} svn−1。
同理我们可以依次计算出所有的
s
v
i
sv_i
svi,于是
a
i
−
1
a_i^{-1}
ai−1 就可以用
s
i
−
1
×
s
v
i
s_{i-1} \times sv_i
si−1×svi 求得。
所以我们就在 O ( n + log p ) O(n + \log p) O(n+logp) 的时间内计算出了 n 个数的逆元。
s[0] = 1;
for (int i = 1; i <= n; ++i) s[i] = s[i - 1] * a[i] % p;
sv[n] = qpow(s[n], p - 2);
// 当然这里也可以用 exgcd 来求逆元,视个人喜好而定.
for (int i = n; i >= 1; --i) sv[i - 1] = sv[i] * a[i] % p;
for (int i = 1; i <= n; ++i) inv[i] = sv[i] * s[i - 1] % p;
倒推法
线性同余方程
a
x
≡
b
(
m
o
d
n
)
ax\equiv b\pmod n
ax≡b(modn)
方程称为 线性同余方程(Linear Congruence Equation)。其中,a、b 和 n 为给定整数,x 为未知数。需要从区间 [0, n-1] 中求解 x,当解不唯一时需要求出全体解。
用逆元求解
首先考虑简单的情况,当 a 和 n 互素,即$ \gcd(a, n) = 1$。
此时可以计算 a 的逆元,并将方程的两边乘以 a 的逆元,可以得到唯一解。
证明
x
≡
b
a
−
1
(
m
o
d
n
)
x\equiv ba ^ {- 1} \pmod n
x≡ba−1(modn)
接下来考虑 a 和 n 不互素(not coprime),即 \gcd(a, n) \ne 1 的情况。此时不一定有解。例如,2x\equiv 1\pmod 4 没有解。
设 g = gcd ( a , n ) g = \gcd(a, n) g=gcd(a,n),即 a 和 n 的最大公约数,其中 a 和 n 在本例中大于 1。
当 b 不能被 g 整除时无解。此时,对于任意的 x,方程 a x ≡ b ( m o d n ) ax\equiv b\pmod n ax≡b(modn) 的左侧始终可被 g 整除,而右侧不可被 g 整除,因此无解。
如果 g 整除 b,则通过将方程两边 a、b 和 n 除以 g,得到一个新的方程:
a
′
x
≡
b
′
(
m
o
d
n
′
)
a^{'}x\equiv b^{'} \pmod{n^{'}}
a′x≡b′(modn′)
其中
a
′
a^{'}
a′ 和
n
′
n^{'}
n′ 已经互素,这种情形已经解决,于是得到
x
′
x^{'}
x′ 作为 x 的解。
很明显, x ′ x^{'} x′ 也将是原始方程的解。这不是唯一的解。可以看出,原始方程有如下 g 个解:
x
i
≡
(
x
′
+
i
⋅
n
′
)
(
m
o
d
n
)
for
i
=
0
…
g
−
1
x_i\equiv (x^{'} + i\cdot n^{'}) \pmod n \quad \text{for } i = 0 \ldots g-1
xi≡(x′+i⋅n′)(modn)for i=0…g−1
总之,线性同余方程的 解的数量 等于
g
=
gcd
(
a
,
n
)
g = \gcd(a, n)
g=gcd(a,n) 或等于 0。
用扩展欧几里得算法求解
根据以下两个定理,可以求出线性同余方程 ax\equiv b \pmod n 的解。
定理 1:线性同余方程 ax\equiv b \pmod n 可以改写为如下线性不定方程:
ax + nk = b
其中 x 和 k 是未知数。这两个方程是等价的,有整数解的充要条件为 \gcd(a,n) \mid b。
应用扩展欧几里德算法
解该线性可以用不定方程。
根据定理 1,对于线性不定方程 ax+nk=b,可以先用扩展欧几里得算法求出一组 x_0,k_0,也就是 ax_0+nk_0=\gcd(a,n),然后两边同时除以 \gcd(a,n),再乘 b。就得到了方程
a
b
gcd
(
a
,
n
)
x
0
+
n
b
gcd
(
a
,
n
)
k
0
=
b
a\dfrac{b}{\gcd(a,n)}x_0+n\dfrac{b}{\gcd(a,n)}k_0=b
agcd(a,n)bx0+ngcd(a,n)bk0=b
于是找到方程的一个解。
定理 2:若
gcd
(
a
,
n
)
=
1
\gcd(a,n)=1
gcd(a,n)=1,且
x
0
、
k
0
x_0、k_0
x0、k0 为方程
a
x
+
n
k
=
b
ax+nk=b
ax+nk=b 的一组解,则该方程的任意解可表示为:
x
=
x
0
+
n
t
,
k
=
k
0
−
a
t
x=x_0+nt,k=k_0-at
x=x0+nt,k=k0−at
并且对任意整数 t 都成立。
根据定理 2,可以从已求出的一个解,求出方程的所有解。实际问题中,往往要求出一个最小整数解,也就是一个特解
x
=
(
x
m
o
d
t
+
t
)
m
o
d
t
x=(x \bmod t+t) \bmod t
x=(xmodt+t)modt
其中有
t
=
n
gcd
(
a
,
n
)
t=\dfrac{n}{\gcd(a,n)}
t=gcd(a,n)n
// 利用extend_gcd求逆元
1 int inverse(int a, int b) {
2 int x, y;
3 extend_gcd(a, b, x, y);
4 return x;
5 }
中国剩余定理
// Chinese Remainder Theorem
1 int CRT(const int a[], const int m[], int n) {
2 int M = 1, ret = 0;
3 for (int i = 1; i <= n; ++i) M *= m[i];
4 for (int i = 1; i <= n; ++i) {
5 int Mi = M / m[i], ti = inv(Mi, m[i]);
6 ret = (ret + a[i] * Mi * ti) % M;
7 }
8 return ret;
10 }