前言
大部分定理的证明是参考的相关资料,因为我是菜狗 qwq,但都是在学习后自己独立写出来的。
因为写的时候是在不同时间写的,所以通读的时候会有一点割裂感。
我一开始写只是方便自己快速复习的,但是写着写着就感觉是在给别人看一样,也不重要了。
带 * 的是不知道放哪里,又感觉另开一个大章太费事,放在需要以这个大章为核心知识的地方。
有错会及时修正,后面的 BSGS 等更高级的如果考完 NOIP 后没退役就会更新。
1 数论中的基础知识
1.1 整除
1.1.1 定义
设
a,b 是整数,如果存在一个整数
c,使得
b=ac,则我们称为
a 整除
b(或
b 被
a 整除),记作
a∣b。
1.1.2 定理
- (反射性)对于所有整数 a,满足 a∣a。
- (传递性)若 a∣b,b∣c,则 a∣c。
- 若 a,b1,b2,⋯,bn 都是整数,并且 a∣bi(1≤i≤n),则 a∣b1c1+b2c2+⋯+bncn 对于所有整数 c1,c2,⋯,cn 成立。
- 若 a,b1,b2,⋯,bn 都是整数,并且 a∣bi(1≤i≤n),则 a∣b1c1×b2c2×⋯×bncn 对于所有整数 c1,c2,⋯,cn 成立。
- 若 a∣b,a∣b±c,则 a∣c。
- 若整数 a,b,c,d,e 满足 a∣b−c,a∣d−e,则 a∣bd−ce。
- 若 a∣b,则对于任意整数 c,满足 ac∣bc。若 ac∣bc,且 c=0,则 a∣b。
1.1.3 证明
定理 1、2、7 可以从定义入手。
定理 3、4 的证明如下:
令
w1,w2,⋯,wn 为满足下列条件的整数:
b1 b2 bn=aw1=aw2⋯=awn
则有:
b1c1 b2c2 bncn=aw1c1=aw2c2⋯=awncn
相加/相乘得:
i=1∑nbicii=1∏nbici=i=1∑nawici=a×i=1∑nwici=i=1∏nawici=an×i=1∏nwici=a×an−1i=1∏nwici
证毕。
定理 5 证明如下:
令
w1,w2 为满足
b=aw1,b+c=aw2 的整数。
令
c=qa,则有
b=aw1=aw2−qa=a(w2−q)。
∴w1=w2−q。
∵w1,w2 为整数。
∴q 为整数,
w2−q 也是整数。
定理 6 证明如下:
令
w1,w2,为满足
b−c=aw1,d−e=aw2 的整数。
则有:
bdbdbdbd−cebd−ce=aw1+c=aw2+e=(aw1+c)(aw2+e)=a2w1w2+aw1e+aw2c+ce=a2w1w2+aw1e+aw2c=a(aw1w2+w1e+w2c)
证毕。
1.2 同余
1.2.1 定义
设
a,b,n 是整数,若
n∣a−b,则称
a 和
b 模
n 同余,记作:
a≡b(modn)
1.2.2 定理
- (反射性)a≡a(modn)。
- (对称性)若 a≡b(modn),则 b≡a(modn)。
- (传递性)若 a≡b(modn),且 b≡c(modn),则 a≡c(modn)。
- 若 a≡c(modn),且 b≡d(modn),则 a+b≡c+d(modn),ab≡cd(modn)。
- 若 a≡b(modn),则 ac≡bc(modnc)。若 ac≡bc(modnc),且 c=0,则 a≡b(modn)。
1.2.3 证明
定理 1、2 可以从定义入手。
定理 3 证明如下:
根据定义
n∣a−b,
n∣b−c。
由整除的定理 3 可以得到:
n∣(a−b)+(b−c)n∣a−c
证毕。
定理 4 的证明如下:
根据定义
n∣a−c,
n∣b−d。
由整除的定理 3 可以得到:
n∣a−c+b−dn∣(a+b)−(c+d)
由整除的定理 6 可以得到:
n∣ab−cd
证毕。
定理 5 的证明可以由整除的定理 7 得到。
1.3 数论函数
定义域为正整数,值域为复数集的子集的函数称为数论函数。
1.3.1 积性函数
对于一个数论函数
f,若
∀x,y∈N+ 且
x 与
y 互质,都有
f(xy)=f(x)f(y),则称
f 为
积性函数。
对于一个数论函数
f,若
∀x,y∈N+,都有
f(xy)=f(x)f(y),则称
f 为
完全积性函数。
可以看出完全积性函数一定是积性函数。
积性函数一定满足
f(1)=1。
一些常见的积性函数:
- 1 函数(完全积性):1(n)=1。
- 幂函数(完全积性):idk(n)=nk。
- 狄利克雷卷积单位元(完全积性):ε(n)={1,n=10,n=1。
- 欧拉函数:φ(n)= 1∼n 中与 n 互质的数的个数。
- 最大公因数:gcdk(n)=gcd(n,k)。
- 除数函数:d(n)= 正整数 n 的正因子个数。
1.3.2 加性函数
对于一个数论函数
f,若
∀x,y∈N+ 且
x 与
y 互质,都有
f(xy)=f(x)+f(y),则称
f 为
加性函数。
对于一个数论函数
f,若
∀x,y∈N+,都有
f(xy)=f(x)+f(y),则称
f 为
完全加性函数。
可以看出完全加性函数一定是加性函数。
加性函数一定满足
f(1)=0。
两个常见加性函数:
- Ω(n)= 所有素因子(含重复)的总个数。(完全加性)
- ω(n)= 不同素因子的个数。
例如
12=22×3,Ω(12)=3,ω(12)=2、
30=2×3×5,Ω(30)=3,ω(30)=3。
1.4 模运算
带余除法:对于整数
a 和
b>0,则存在唯一的整数
q,r,满足
a=bq+r,其中
0≤r<b,其中
q 为商,
r 为余数。
余数
r 用
amodb 来表示。
带余除法非常重要,在很多题目中都能用带余乘法拆分得到关键步骤。
一些运算法则:
- (a+b)modM=(amodM+bmodM)modM。
- (a−b)modM=(amodM−bmodM)modM。
- (a×b)modM=(amodM×bmodM)modM。
千万千万要注意除法没有类似的运算法则!!!!
关于除法的模运算详见“模意义下的乘法逆元”。
2 素数
对于正整数
p>1,若
p 的因数只有
1 和它本身,则
p 是素数。
2.1 唯一分解定理
每个大于
1 的整数都能唯一的表示成其质因数之积。
即
n=∏piai (
pi 为素数且
p1<p2<⋯,ai≥1 )。
结论比较显然,故不给出该定理的证明。
求解代码:
CPPvoid decompose(int x){
for(int i=2;i*i<=x;++i)
while(x%i==0) ++a[i],x/=i;
if(x) ++a[x];
}
int main(){
int n;scanf("%d",&n);
decompose(n);
for(int i=1;i<=n;++i)
if(a[i]) printf("%d %d\n",a[i],i);
}
- 一个真命题: n 中最多含有一个大于 n 的因子。
证明:如果存在两个大于
n 的因子,则二者相乘大于
n,矛盾。
2.2 费马小定理
若一个素数
p,
a 是与
p 互质的任意整数,有
ap−1≡1(modp)。等价地,
ap≡a(modp)。
- 对于每一个整数 i∈[1,p),满足 i×amodp 互不相同。
证明:如果存在整数
i=j 且
i,j∈[1,p),满足
i×a≡j×a(modp),则
i≡j(modp),不符合定义。
显然有:
i=1∏p−1i≡i=1∏p−1(i×a)≡ap−1i=1∏p−1i(modp)
根据同余的定理 5 可以得到:
ap−1ap≡1(modp)≡a(modp)
得证费马小定理。
实际上,费马小定理是欧拉定理的一种特殊情况,后文的欧拉定理会提及。
2.3 素数筛
2.3.1 普通筛
既然是筛法,就不能一个数一个数暴力求是不是素数,这个复杂度
O(nn) 妥妥 T 飞。
一个大于
1 的整数显然要么素数,要么是合数。
根据素数定义,一个数是素数当且仅当其因数只有
1 和它本身。
那么对于任意大于
1 的整数
i,j,
i×j 必定不是素数,那么它就是合数,这样就得到了时间复杂度为
O(nlogn) 普通筛:
CPPfor(int i=2;i<=n;++i){
if(!vis[i]) prime[++tot]=i;
for(int j=2;j*i<=n;++j)
vis[j*i]=1;
}
2.3.2 埃氏筛
上面的筛法也太慢了,比如
12=3×4,
i=3 或
i=4 时都会把
12 筛去,我们需要更快的筛法。
不难发现,根据唯一分解定理,一个合数一定会被拆成若干质因子之积。
这样就可以把质数的倍数筛出来,就可以避免前文的例子中
i=4 这样枚举合数的倍数这种纯浪费时间的情况。
时间复杂度
O(nloglogn),作者不会证复杂度 qwq。
CPPfor(int i=2;i<=n;++i){
if(!vis[i]){
prime[++tot]=i;
for(int j=2;j*i<=n;++j)
vis[i*j]=1;
}
}
既然素数的(大于
1 的)整数倍是合数,那么(大于
1 的)整数的素数倍也是合数,那么就可以得到埃氏筛的另外一种形式:
CPPfor(int i=2;i<=n;++i){
if(!vis[i]) prime[++tot]=i;
for(int j=1;j<=tot && i*prime[j]<=n;++j)
vis[i*prime[j]]=1;
}
2.3.3 线性筛
埃氏筛已经够优秀了,但是带个常数还是太慢了,有没有什么更加快速的筛法吗。
有的兄弟有的,线性筛的复杂度只有
O(n)。
线性筛的代码与埃氏筛形式 2 相比只多了一行:
CPPfor(int i=2;i<=n;++i){
if(!vis[i]) prime[++tot]=i;
for(int j=1;j<=tot && i*prime[j]<=n;++j){
vis[i*prime[j]]=1;
if(i%prime[j]==0) break;
}
}
线性筛的思想是,对于一个合数
n,设
n 的最小质因子为
pn,则
n 会且仅会在
i=pnn 被筛去。
正确性是显然的,接下来证明充要性。
充分性证明(合数
n 会在
i=pnn 时被筛去):因为
pn 是
n 的最小质因子,所以
pnn≥pn,那么在
i=pnn 时,
pn 就已经被记录为素数了。且根据唯一分解定理,
pnn 的质因子一定大于等于
pn。
当
i=pnn 时,如果出现
prime[j] 还没有枚举到
pn 就终止,那么此时
prime[j]<pn 且
prime[j] 一定是
i=pnn 的一个质因子,这与
pn 是
n 的最小质因子矛盾。得证。
必要性证明(合数
n 仅会在
i=pnn 时被筛去):假设
p′ 是
n 的一个质因子且
p′>pn,那么根据唯一分解定理,
pn 也一定是
p′n 的一个质因子,即
pn∣p′n。所以,当
i=p′n 时,当
prime[j] 枚举到
pn,因为
pn∣p′n,此时枚举终止,也就不会被
p′ 筛去。
这样,每个合数都只会被
vis[i*prime[j]]=1 标记一次,所有的数总共不会被标记超过
n 次,所以线性筛的时间复杂度为
O(n)。
*2.3.4 线性筛求积性函数
所有的积性函数都可以用线性筛来求。
举一个线性筛求
d(n) 的例子。
既然是线性筛,就要从唯一分解和最小质因子的角度出发。
对于
n>1 的情况,设
P(n) 是
n 的最小质因子,
K(n) 是
n 最小质因子的指数,相当于把
n 唯一分解后的
p1 和
k1。
因为
d(n) 是积性函数且
P(n)K(n)n 与
P(n)K(n) 显然互质,所以
d(n)=d(P(n)K(n)n)×d(P(n)K(n))=d(P(n)K(n)n)×(K(n)+1)。
P(n) 在线性筛时就能顺便求出来,所以考虑求
K(n)。
- 若 P(n)=P(P(n)n),那就是没有多余的最小质因子,此时 K(n)=1。
- 若 P(n)=P(P(n)n),这样也很简单,只要把指数加一继承一下就行了:K(n)=K(P(n)n)+1。
知道这些就够用了。
求解代码:
CPPd[1]=d[0]=1;
for(int i=2;i<=n;++i){
if(!vis[i]){
prime[++tot]=i;
P[i]=i,A[i]=1;
d[i]=2;
}
else{
if(P[i]!=P[i/P[i]]) A[i]=1;
else A[i]=A[i/P[i]]+1;
d[i]=(A[i]+1)*d[i/pow(P[i],A[i])];
}
for(int j=1;j<=tot&&i*prime[j]<=n;++j){
vis[i*prime[j]]=1;
P[i*prime[j]]=prime[j];
if(i%prime[j]==0) break;
}
}
3 欧拉函数与欧拉定理
3.1 欧拉函数
欧拉函数
φ(n) 表示
1∼n 中与
n 互质的数的个数,是积性函数。
3.1.1 求单个欧拉函数
假设要求
φ(n),根据唯一分解定理,
n=∏piki,
pi 是质数,且
ki>0。
那么根据欧拉函数积性性质
φ(n)=∏φ(piki),考虑怎么求
φ(pk)。
可以发现,如果一个数与
pk 不互质,那么其一定是
p 的倍数,所以和
pk 不互质的数的个数是
ppk=pk−1,反过来就得到了
φ(pk)=pk−pk−1=pk(1−p1)。
那么
φ(n)=∏φ(piki)=∏piki(1−pi1)=n∏(1−pi1)
这样就可以在
O(n) 的时间复杂度下求出
φ(n):
CPPint tphi(int n) {
int ans=n;
for(int i=2;i*i<=n;++i)
if(n%i==0){
ans=ans/i*(i-1);
while(n%i==0) n/=i;
}
if(n!=1) ans=ans/n*(n-1);
return ans;
}
3.1.2 线性筛求多个欧拉函数
既然欧拉函数是积性函数,我们就能用线性筛来求
1∼n 的欧拉函数。
若
i 是素数,那么
φ(i)=i−1。
若
i 是合数,在线性筛中一个合数被筛去当且仅当被其最小质因数筛去,假设
p1 是
i 的最小质因子,
k1 是
i 的最小质因子的指数,分类讨论:
- k1=1 时,此时 p1 与 p1i 互质,所以 φ(i)=φ(p1i)×φ(p1)=φ(p1i)×(p1−1)。
- k1>1 时,此时 p1 与 p1i 不互质,p1i 的最小质因数仍然是 p1,因为:
φ(i)φ(p1i)=i∏(1−pi1)=p1i∏(1−pi1)
所以
φ(i)=φ(p1i)×p1。
CPPvoid sol(int n){
phi[1]=1;
for(int i=2;i<=n;++i){
if(!phi[i]) phi[i]=i-1,prime[++tot]=i;
for(int j=1;j<=tot&&i*prime[j]<=n;++j){
if(i%prime[j]==0){
phi[i*prime[j]]=phi[i]*prime[j];
break;
}
else
phi[i*prime[j]]=phi[i]*(prime[j]-1);
}
}
}
3.1.3 欧拉函数的其他性质
一个最重要的就是:
n=∑d∣nφ(d) 对任意正整数
n 成立。
我们来证明这个,设集合
A={1,2,⋯,n},并将该集合划分成若干个子集
Sd={k∈A∣gcd(k,n)=d},显然任意两个
S 的交集为空,且这些的并集等于
A,所以
n=∣A∣=∑∣Sd∣,而且
d∣n,故
n=∑d∣n∣Sd∣。
假设
Sd 中一个元素为
k,有
gcd(k,n)=d,设
k=dm,
m 是正整数,显然
m 能取的数量就是
∣Sd∣。所以
k=dm≤n,
m≤dn。又
gcd(dm,n)=d,
gcd(m,dn)=1。
令
t=dn,所以
1≤m≤t 且
gcd(m,t)=1,
m 的取到的数量就是
φ(t)=φ(dn),即
∣Sd∣=φ(dn)。
d∣n,所以
dn 是整数,且是
n 的一个约数。
现在有了
n=∑d∣nφ(dn),发现在枚举
d 时,
dn 都是
n 的正约数且成对,即
d∣n 时,
nd∣n。因为对答案影响只有
φ(dn),所以上述等式等价于
n=∑d∣nφ(d)。得证。
不要问为什么最后证的这么牵强,这是我自己证的,能大概证出来就已经是我这个菜狗的极限了。
3.2 欧拉定理
欧拉定理和扩展欧拉定理常由于解决大指数化简的问题。
设
a,n∈N+,若
a 与
n 互质,则
aφ(n)≡1(modn)。
n 为素数时,
φ(n)=n−1,此时欧拉定理变成费马小定理。
那就考虑
n 为其他数,设集合
A 是所有与
n 互质的正整数,即
A={x1,x2,⋯,xφ(n)}。
令集合
B 为集合
A 中每一个元素乘
a 模
n 构成的集合,即
B={ax1modn,ax2modn,⋯,axφ(n)modn},那么
A=B。
若存在
i=j,axi≡axj(modn),那么
a(xi−xj)≡0(modn)。因为
a 与
n 互质,
0<xi,xj<n 且
xi=xj,故一定不存在一个
(xi−xj) 使得
a(xi−xj)≡0(modn) 成立,得证。
因为
xi 与
n 互质,
a 也与
n 互质,所以
axi 与
n 互质。
A 包括了
所有与
n 互质的小于
n 的正整数。所以每一个
0<aximodn<n 都与
A 中的一个元素对应,又
∣B∣=∣A∣ 且
B 中每个元素互不相同,所以
A=B。
那么有:
i=1∏φ(n)axiaφ(n)i=1∏φ(n)xiaφ(n)≡i=1∏φ(n)xi(modn)≡i=1∏φ(n)xi(modn)≡1(modn)
得证欧拉定理。
3.3 扩展欧拉定理
设
a,n∈N+,有
a2φ(n)≡aφ(n)(modn)。
等价地,对于任意的
a,k,n∈N+,若
k≥φ(n),那么有
ak≡akmodφ(n)+φ(n)(modn)。
证明:
咕咕咕。
4 二元线性不定方程
一般来说,形如方程
ax+by=c,其中
a,b,c 是整数,求整数
x,y。通常使用裴蜀定理和扩展欧几里得算法来求解。与普通的欧几里得算法(辗转相除法)相似。
4.1 裴蜀定理
若
a,b 不是全为 0 的整数,那么对于任意整数
x,y 满足
gcd(a,b)∣ax+by,且存在整数
x,y,使得
ax+by=gcd(a,b)。
下面是裴蜀定理的证明:
设集合
S 为所有可以表示成
ax+by 的数,即:
S={ax+by,x∈Z,y∈Z}
设
d 是集合
S 中的最小正整数(
d=ax0+by0),则有:
- ∀w,w∈S,则有 d∣w。
证明:假设
d∤w,则存在
x′,y′ 使得
d∤ax′+by′。由带余除法的定义可知:
ax′+by′=qd+r,其中
0<r<d。那么有:
r=ax′+by′−qd=ax′+by′−q(ax0+by0)=a(x′−qx0)+b(y′−qy0)
则
r 是比
d 更小,且在集合
S 中的正整数。故假设不成立,证毕。
当
x=1,y=0 时,
ax+by=a。
当
x=0,y=1 时,
ax+by=b。
则有
d∣a,
d∣b,所以
d 是
a,b 的公约数。
∀c,
c 是
a,b 的公约数。
则
c∣a,c∣b,那么有
a=m1c,b=m2c,可以得到:
d=m1cx0+m2cy0=c(m1x0+m2y0)
所以
c∣d,
d 是
a,b 的最大公约数,得证。
4.2 扩展欧几里得(exgcd)
已知整数
a,b,c,求二元方程
ax+by=c 的整数解。
4.2.1 求特解
由裴蜀定理可知若
gcd(a,b)∤c 则无解,反之有解。即
gcd(a,b) 是
c 的倍数。
那么只需要求
ax+by=gcd(a,b) 的一组解,然后把解同时乘以
gcd(a,b)c 即可。
因为
gcd(a,b)=gcd(b,amodb)。
所以
bx0+(amodb)y0=gcd(b,amodb)。
如果重复上述操作可以得到:
a′x′+0y′x′=1=gcd(a′,0)=a(①),y′=0
考虑回代。
假设已经知道了
bx0+(amodb)y0=gcd(b,amodb) 的一组解,如何求
ax+by=gcd(a,b)。
因为
gcd(a,b)=gcd(b,amodb),所以:
ax+by=bx0+(amodb)y0=bx0+(a−⌊ba⌋b)y0=bx0+ay0−⌊ba⌋by0=ay0+b(x0−⌊ba⌋y0)
即:
{x=y0y=x0−⌊ba⌋y0
这样就可以递归找出特解了。
注意式子
①,这里的
y′ 可不为
0,
y′ 取其它整数虽导致得到的最终结果不同,但是符合题意的一组解,不影响答案。
求解代码:
CPPvoid exgcd(int a,int b,int &x,int &y){
if(b==0){
x=1; y=0;
return ;
}
exgcd(b,a%b,x,y);
int tx=x;
x=y;
y=tx-a/b*y;
}
不要忘了最后的解要乘
gcd(a,b)c。
4.2.2 求通解
这个方程显然是有很多个解的,那么如何求所有的解。
现在已经求出了
ax+by=c 的一组解,假设另一个解
ax′+by′=c。
两式子相减得:
a(x−x′)+b(y−y′)=0。
令
Δx=x−x′,Δy=y−y′,这个方程的的任何一个解与已经求出的特解的差
(Δx,Δy),也一定满足
(aΔx+bΔy)=c。
对于该方程的任意一组解
(x′′,y′′),因为
(ax′′+by′′)+(aΔx+bΔy)=c+0=c,故
(x′′+Δx,y′′+Δy) 也是该方程的一组解。
因此只需求出
aΔx+bΔy=0 的所有解即可。
因为对于全部的解
x 的绝对值越大,
y 的绝对值显然越大。
所以令方程
ax+by=0 的一组非零解为
(xmin,ymin),指
x,y 的绝对值最小的一组解。
因为
∣ax∣ 是
a 的倍数,
∣by∣ 是
b 的倍数,而且
∣ax∣=∣by∣。
所以
∣ax∣、
∣by∣ 是
a,b 的公倍数。
要让
∣ax∣ 最小,
∣a∣ 是定值,就是让
∣x∣ 最小,即
a,b 的最小公倍数
lcm(a,b)=gcd(a,b)a×b。
因此最小的一组非零解就是
(xmin,ymin)=(gcd(a,b)b,gcd(a,b)−a)。
可以证明所有关于
ax+by=0 的解都是
(xmin,ymin) 的倍数。
令
k∈Z,
(x,y) 是得到的特解,那么就得到了通解形式,即
ax+by=c 的所有解:
(x+kgcd(a,b)b,y−kgcd(a,b)a)
5 模意义下的乘法逆元
模意义下的乘法逆元简称“逆元”。
若存在一个整数
x,使得
ax≡1(modp),则称
x 为
a 在模
p 意义下的乘法逆元,即为
a−1(modp)。
5.1 逆元的求法
5.1.1 扩展欧几里得算法求逆元
ax≡1(modp) 可以拆成同余方程
ax+py=1,求得的
x 就是
a 在模
p 意义下的乘法逆元。
由裴蜀定理可以发现存在
a 在模
p 意义下的乘法逆元当且仅当
a 与
p 互素。
5.1.2 费马小定理求逆元
利用费马小定理
ap−1≡1(modp),可以改写等式:
ap−1=a×ap−2≡1(modp),显然
ap−2 就是逆元。
但是费马小定理要求
p 是质数且
a 不能是
p 的倍数,前者限制条件在扩展欧几里得里没有要求,所以用扩展欧几里得求逆元比费马小定理求逆元的实用性更广。
5.2 逆元的性质
唯一存在性:
由上文求逆元的方式可知存在
a 在模
p 意义下的乘法逆元只需要满足
a 与
p 互素,且
0<a−1<p,这个逆元是唯一确定的。
证明很简单:假设存在
0<x1,x2<p,
x1<x2。那么
ax1≡ax2(modp),
a(x2−x1)≡0(modp)。因为
a 与
p 互素,所以
x2−x1 是
p 的倍数,但是
0<x2−x1<p,不是
p 的倍数。与前提假设矛盾,得证。
值得注意的是,逆元的 “唯一性”是指在模
p 的意义下,如果只是根据定义来解那么是有很多解的,例如
3−1≡5(mod7),
12 和
19 也可以表示,与
5(mod7) 等价。
其他相对来说没那么重要的性质:
运算兼容性:(a×b)−1≡a−1×b−1(modp)。
互逆性: 若
0<a,b<p,
ab≡1(modp),那么
a 是
b 在模
p 意义下的乘法逆元,
b 也是
a 在模
p 意义下的乘法逆元。
5.3 逆元的作用
在进行模运算时有时会出现求
bamodp 的情况,根据模运算的运算规律除法是不能直接模运算的,但是利用逆元
b×b−1≡(modp) 可以化成
ba×b×b−1≡a×b−1(modp) 这样乘的形式,就可以直接进行模运算了。
而且在处理
ax≡b(modp) 这样的方程时,两边同时乘
a−1 可以化简为
x≡b×a−1(modp)。
在计算组合数
Cmn=n!(m−n)!m! 时也可以利用逆元将分母转换为乘法。
5.4 *威尔逊定理
同余式
(p−1)!≡−1(modp) 成立的充要条件是
p 为素数。
必要性证明(
p 是素数
⇒ (p−1)!≡−1(modp)):
设集合
A={x∣1≤x<p,x∈N}。那么
∀d∈A,
d 在模
p 意义下的乘法逆元
d−1 显然存在,且根据逆元的唯一性,
d−1∈A。
由根据逆元的互逆性:
1×2×3×⋯×(p−1)=1−1×2−1×⋯×(p−1)−1=(p−1)!
因为
p−1≡−1(modp) 且
p−1=p,又
1=1−1,且剩下的元素能两两配对,故:
1×2×2−1×⋯×(p−1)≡1×1×⋯×−1(modp)
即:
(p−1)!≡−1(modp)
充分性证明(
(p−1)!≡−1(modp) ⇒ p 是素数):
假设
p 是合数,则存在一个整数
1<d<p,使得
d∣p。
显然有:
d∣(p−1)!,即
(p−1)!≡0(modd)。
由已知条件:
(p−1)!≡1(modp),由
d 与
p 的关系和上述同余式可以得到:
0≡−1(modd)
显然
d=±1,但是
d>1,故假设不成立,得证。
6 线性同余方程组
形如:
⎩⎨⎧x≡a1x≡a2x≡a3x≡an(modm1)(modm2)(modm3)⋯(modmn)
的方程称为线性同余方程组,对于模数互质的特殊情况,可以用中国剩余定理(CRT)解决。
对于一般情况就只能使用扩展中国剩余定理(exCRT)解决。
6.1 中国剩余定理(CRT)
CRT 只能用来解决
mi 两两互质的情况。
令
M=∏mi,Mi=miM。
显然
Mi 与
mi 互质,则
Mi 在模
mi 意义下的乘法逆元
Mi−1 存在。
即:
Mi×Mi−1≡1(modmi),
aiMiMi−1≡ai(modmi)。
对于
j=i,因为
Mj=∏i=jmi,则
Mj 是
mi 的倍数。
所以
ajMjMj−1≡0(modmi)。(注意,这里
Mj−1 是指模
mj 意义下的逆元,后面的也是。)
令
x=∑aiMiMi−1。
x≡∑aiMiMi−1≡aiMiMi−1+i=j∑ajMjMj−1≡ai+i=j∑0≡ai(modmi)
- 对于 k∈Z,那么 x+kM 也是该方程的解。
证明:
kM≡0(modmi),x+kM≡kM+∑aiMiMi−1≡0+ai≡ai(modmi)。
- 不存在其他解。
证明:假设存在另一个解
x′,显然满足
x′≡x(modM)。
但是
x′≡ai(modmi),x≡ai(modmi)。
所以
x′−x≡0(modmi) 对所有
i 成立。
因为
mi 两两互质,所以
lcm(m1,m2,⋯,mn)=m1×m2×⋯×mn=M。
故
x′−x≡0(modM),与前提假设矛盾。得证。
6.2 扩展中国剩余定理(exCRT)
把“
mi 两两互质的条件”删除时,用 exCRT。
exCRT 本质上与 CRT 完全不同,CRT 的核心思想是利用逆元求解,这里没有了互质的条件,意味着核心思想变了。所以 exCRT 和 CRT 就是完全不同的两种算法,只是解决的问题相似而已。
如果方程组只有一个方程:
x≡a(modm),那么该方程的最小非负整数解显然为
a。
如果只有两个方程
{x≡a1(modm1)x≡a2(modm2),因为一个方程可以直接求出答案,所以考虑把这两个方程合并成一个方程:
把同余式改写成等式:
x=a1+k1m1=a2+k2m2。
移项:
k1m1−k2m2=a2−a1。
这刚好是一个二元方程,可以用 exgcd 求解
k1。
注意,根据裴蜀定理,若
gcd(m1,m2)∤(a2−a1) 则无解。
求解出
k1 后,可以得到一个特解
x′=a1+k1m1。
现在已经得到了特解,那么
{x≡a1(modm1)x≡a2(modm2) 的通解为
x′+k×lcm(m1,m2),其中
k∈Z 。
这很显然,
lcm(m1,m2) 同时是
m1 和
m2 的倍数,故
{x+k×lcm(m1,m2)≡a1+0(modm1)x+k×lcm(m1,m2)≡a2+0(modm2)。
我们令
x0 是通解中的最小非负整数,那么原来的两个方程可以合并为:
x≡x0(modlcm(m1,m2))
这里的
x0 显然小于
lcm(m1,m2),并且没有其他大于等于零小于
lcm(m1,m2) 的整数解,这里由通解就能直接看出来,不再证明。
合并方程就是 exCRT 的核心操作,如此反复执行合并操作,就可以把原来的
n 个方程合并成一个方程,进而得到解。
CPPsigned main(){
int n,a1,b1,a2,b2; scanf("%lld%lld%lld",&n,&a1,&b1);
for(int i=1;i<n;++i){
scanf("%lld%lld",&a2,&b2);
int k1,k2;
int d=exgcd(a1,a2,k1,k2);
int bg=a2/d;
if((b2-b1)%d!=0) return !printf("Impossbile\n");
k1=(mul(k1,(b2-b1)/d,bg));
b1=k1*a1+b1;
a1=a1*bg;
b1=(b1%a1+a1)%a1;
}
printf("%lld\n",b1);
}
}
7 组合数学与计数
7.1 二项式定理
若
n 是正整数,则有:
(x+y)n=i=0∑nCnixiyn−i。
用数学归纳法证明:
假设
n=k 时原式成立,则
n=k+1 时,有:
(x+y)k+1=(x+y)(x+y)k=(x+y)i=0∑kCkixiyk−i=(x+y)(Ck0yk+Ck1xyk−1+⋯+Ckk−1xk−1y+Ckkxk)=xk+1+yk+1+(Ck0+Ck1)xyk+(Ck1+Ck2)x2yk−1+⋯+(Ckk−1+Ckk)xky=xk+1+yk+1+i=1∑k(Cki−1+Cki)xiyk−i+1
因为
Cki−1+Cki=(i−1)!(k−i+1)!k!+i!(k−i)!k!=i!(i−1)!(k−i)!(k−i+1)!k!i!(k−i)!+k!(i−1)!(k−i+1)!=i!(k−i+1)!(k+1)!=Ck+1i
所以
(x+y)k+1=xk+1+yk+1+i=1∑kCk+1ixiyk−i+1=i=0∑k+1Ck+1ixiyk−i+1
因此
n=k+1 时原式也成立,得证。
7.2 卢卡斯定理(Lucas 定理)
一个引理:若
p 是素数,则有:
(x+y)p≡xp+yp(modp)。
证明:由二项式定理可知:
(x+y)p=i=0∑pCpixiyp−i。
其中当
1≤i<p 时:
Cpi=i!(p−i)!p!=i×(i−1)!(p−i)!p×(p−1)!=ipCp−1i−1
所以
Cpi≡ipCp−1i−1≡p×i−1Cp−1i−1≡0(modp)
其中
i−1 表示
i 在模
p 意义下的乘法逆元。
原式只剩下
i=0,p 两项,得证。
Lucas 定理:
若
p 是素数,则有:
Cnm≡C⌊pn⌋⌊pm⌋×Cnmodpmmodp(modp)。
证明:
根据带余除法,令
n=ap+b,m=cp+d,其中
0≤b,d<p。
根据二项式定理得到式子一:
(1+x)n≡i=0∑nCnixi(modp)
根据二项式定理和引理得到式子二:
(1+x)n≡(1+x)ap+b≡((1+x)p)a×(1+x)b≡(1+xp)a×(1+x)b≡(i=0∑aCaixip)(j=0∑bCbjxj)(modp)
由式子一可知
xm 的系数为
Cnm。
由式子二可知
xm=xcp+d 的系数为
CacCbd。
因为
⌊pn⌋=a,⌊pm⌋=c,nmodp=b,mmodp=d。
所以
Cnm≡C⌊pn⌋⌊pm⌋×Cnmodpmmodp(modp),证毕。
在求解时,根据费马小定理:
(m!)p−1≡1(modp),[(n−m)!]p−1(modp)。
那么有:
Cnm=m!(n−m)!n!≡n!×m!p−2×(n−m)!p−2(modp)
这样就可以求解了。
参考资料
大致是按参考程度排列的。