竞赛中会用到的初等数论
0. 线性筛
[ 1 , n ] [1,n] [1,n]的范围内找质数,复杂度线性 O ( n ) O(n) O(n)。
基于一个简单的想法:每个合数只在他的最小质因数删去。
我们要删去的数
x
x
x,
x
=
p
0
×
f
n
t
l
x=p_{0}\times f_{ntl}
x=p0×fntl
其中
p
0
p_{0}
p0为
x
x
x的最小质因数,
f
n
t
l
f_{ntl}
fntl为
x
x
x的次大因数。
void GetPrime(int n)
{
memset(isPrime, 1, sizeof(isPrime));
isPrime[1] = 0;
for(int i = 2; i <= n; i++) //穷举次大因数
{
if(isPrime[i])
Prime[++cnt] = i;
for(int j = 1; j <= cnt && i*Prime[j] <= n; j++) //穷举最小质因数
{
isPrime[i*Prime[j]] = 0;
if(i % Prime[j] == 0) break; //当i里有Prime[j]这个因子的时候,Prime[j+1]一定不是i*Prime[j+1]的最小质因数,所以终止,下个不用做了,因为不满足最初的"简单的想法"
}
}
}
后话:如果把 i s P r i m e [ i ] isPrime[i] isPrime[i]看成一个函数的话,表示i是不是一个质数,那么这里其实是在用递推求值。边界条件其实是 i i i为质数的时候,函数的值为1。当然这个函数不满足积性(下一节会讲到)。
1. 欧拉函数
欧拉函数 ϕ ( x ) \phi(x) ϕ(x),表示的是范围 [ 1 , x ] [1,x] [1,x]中与x互质的整数的个数。举几个例子, ϕ ( 1 ) = 0 , ϕ ( 2 ) = 1 , ϕ ( 3 ) = 2 , ⋯ \phi(1)=0,\ \phi(2)=1,\ \phi(3)=2,\ \cdots ϕ(1)=0, ϕ(2)=1, ϕ(3)=2, ⋯
容易观察到,对于任意一个质数 p p p, ϕ ( p ) = p − 1 \phi(p)=p-1 ϕ(p)=p−1
接下来考虑
ϕ
(
p
k
)
\phi(p^k)
ϕ(pk),由于
p
k
p^k
pk只有唯一的质因数p,所以一个与其不互质的数一定包含因子p。所以
[
1
,
p
k
]
[1,p^k]
[1,pk]中的p的倍数都与
p
k
p^k
pk不互质,其他都与其互质。这个范围内p的倍数总共有
p
k
−
1
p^{k-1}
pk−1个。因此,
ϕ
(
p
k
)
=
p
k
−
p
k
−
1
=
(
p
−
1
)
p
k
−
1
\phi(p^k)=p^k-p^{k-1}=(p-1)p^{k-1}
ϕ(pk)=pk−pk−1=(p−1)pk−1
下面证明一下
ϕ
(
x
)
\phi(x)
ϕ(x)具有一下性质,
对于
(
x
,
y
)
=
1
(x,y)=1
(x,y)=1,有
ϕ
(
x
⋅
y
)
=
ϕ
(
x
)
⋅
ϕ
(
y
)
\phi(x\cdot y)=\phi(x)\cdot \phi(y)
ϕ(x⋅y)=ϕ(x)⋅ϕ(y)
这里用Dirichlet卷积,对交换代数有兴趣的话,同样也可以验证环同态,这个放在Appendix里。
考虑集合
A
d
=
{
i
∣
(
x
,
i
)
=
d
}
,
d
∣
x
即
d
为
x
的
一
个
因
数
。
A_d=\{i|(x,i)=d\},\ d|x\ 即d为x的一个因数。
Ad={i∣(x,i)=d}, d∣x 即d为x的一个因数。
∣
A
d
∣
=
ϕ
(
x
/
d
)
|A_d|=\phi(x/d)
∣Ad∣=ϕ(x/d)
显然有上式(觉得不显然的可以考虑
i
=
k
⋅
d
i=k\cdot d
i=k⋅d的系数k,满足条件时,有几种取值),
x = ∑ d ∣ x ϕ ( x / d ) x=\sum_{d|x}\phi(x/d) x=d∣x∑ϕ(x/d)
写成Dirichlet卷积形式
1 ∗ ϕ ( x ) = ∑ d ∣ x ϕ ( x / d ) = x 1*\phi(x)=\sum_{d|x}\phi(x/d)=x 1∗ϕ(x)=d∣x∑ϕ(x/d)=x
1的卷积逆是Mobius的 μ \mu μ, 所以 ϕ ( x ) = μ ∗ x \phi(x)=\mu*x ϕ(x)=μ∗x,两个积性函数的卷积还是积性函数,所以欧拉函数也是积性函数。
有了积性和唯一分解定理可以写出欧拉函数的通项
x的唯一质因数分解:
x
=
p
1
k
1
p
2
k
2
⋯
p
n
k
n
x=p_1^{k_1} p_2^{k_2}\cdots p_n^{k_n}
x=p1k1p2k2⋯pnkn
t
h
e
n
ϕ
(
x
)
=
(
p
1
−
1
)
k
1
−
1
(
p
2
−
1
)
k
2
−
1
⋯
(
p
n
−
1
)
k
n
−
1
then\ \phi(x)=(p_1-1)^{k_1-1}(p_2-1)^{k_2-1}\cdots (p_n-1)^{k_n-1}
then ϕ(x)=(p1−1)k1−1(p2−1)k2−1⋯(pn−1)kn−1
然后可以愉快的用这三个式子来做递推
ϕ ( x ) = x − 1 x 为 质 数 ϕ ( i × p r i m e ( j ) ) = ϕ ( i ) × ϕ ( p r i m e [ j ] ) ( i , p r i m e [ j ] ) = 1 ϕ ( i × p r i m e ( j ) ) = ϕ ( i ) × p r i m e [ j ] ( i , p r i m e [ j ] ) = p r i m e [ j ] \begin{aligned} \phi(x) &= x-1 & x为质数 \\ \phi(i\times prime(j))=&\phi(i)\times \phi(prime[j]) &(i,prime[j])=1\\ \phi(i\times prime(j))=&\phi(i)\times prime[j] &(i,prime[j])=prime[j]\\ \end{aligned} ϕ(x)ϕ(i×prime(j))=ϕ(i×prime(j))==x−1ϕ(i)×ϕ(prime[j])ϕ(i)×prime[j]x为质数(i,prime[j])=1(i,prime[j])=prime[j]
void GetPrime(int n)
{
memset(isPrime, 1, sizeof(isPrime));
isPrime[1] = 0;
for(int i = 2; i <= n; i++) //穷举次大因数
{
if(isPrime[i]){
Prime[++cnt] = i;
phi[i]=i-1;//i为质数
}
for(int j = 1; j <= cnt && i*Prime[j] <= n; j++) //穷举最小质因数
{
isPrime[i*Prime[j]] = 0;
phi[i*Prime[j]]=phi[i]*phi[Prime[j]];//i Prime[j]互质
if(i % Prime[j] == 0) {
phi[i*Prime[j]]=phi[i]*Prime[j];//i Prime[j]不互质
break;
}
}
}
}
求单个数的欧拉函数可以用通项和因式分解求。
同样利用
∣
A
d
∣
=
ϕ
(
x
/
d
)
|A_d|=\phi(x/d)
∣Ad∣=ϕ(x/d)
可以使用分块法解决一些求和问题,比如求
∑
i
=
1
n
(
i
,
n
)
=
∑
d
∣
n
d
×
ϕ
(
n
/
d
)
\sum_{i=1}^n (i,n)=\sum_{d|n} d\times \phi(n/d)
∑i=1n(i,n)=∑d∣nd×ϕ(n/d)
习题:P2158
2. 费马小定理和欧拉定理
i.欧拉定理
对于任意正整数a和x, a ϕ ( x ) ≡ 1 m o d x a^{\phi(x)}\equiv 1 \mod x aϕ(x)≡1modx
ii.费马小定理
对于任意正整数a和质数p,
a
p
−
1
≡
1
m
o
d
p
a^{{p-1}}\equiv 1 \mod p
ap−1≡1modp
证明放在附录里,用的是群论的Lagrange Theorem
费马小定理可以用来判断一个数质数,用快速幂可以达到
O
(
lg
n
)
O(\lg n)
O(lgn)的复杂度,也可以用来求一个数关于p的数论倒数
a
(
p
−
2
)
a
≡
1
m
o
d
p
a^{(p-2)} a \equiv 1\mod p
a(p−2)a≡1modp
a
(
p
−
2
)
≡
a
−
1
m
o
d
p
a^{(p-2)} \equiv a^{-1} \mod p
a(p−2)≡a−1modp
3. 裴蜀定理
两个整数
a
,
b
a , b
a,b, 最大公约数为
(
a
,
b
)
=
d
(a,b)=d
(a,b)=d,
∃
\exist
∃整数
x
,
y
x,\ y
x, y, 满足
a
x
+
b
y
=
d
;
ax+by=d;
ax+by=d;
∀
\forall
∀整数
x
,
y
x,\ y
x, y,
a
x
+
b
y
≡
0
m
o
d
d
ax+by\equiv 0 \mod d
ax+by≡0modd
证明很简单,这里就不展开讲了 有兴趣的同学自己去证明一下。
下面一节会去解决这个求这个a, b的问题。
4. 辗转相除和扩展欧几里得以及求逆元
辗转相除法可以看成一个递归, 递归式是
(
a
,
b
)
=
(
b
,
a
%
b
)
(a,b)=(b,a\%b)
(a,b)=(b,a%b),边界条件为
(
a
,
0
)
=
a
(a,0)=a
(a,0)=a.
正确性很容易证明,复杂度在1844年被一个法国人计算出来,结果是不会大于
5
lg
m
i
n
(
a
,
b
)
5\lg min(a,b)
5lgmin(a,b),标志着算法复杂度理论的开端。
这里提供一种构造Fibonacci的夹逼证明,
Proof
Statement 1: 如果一组a, b在n步辗转相除计算出结果,那么有
a
>
=
f
n
+
2
b
>
=
f
n
+
1
a>=f_{n+2}\\b>=f_{n+1}
a>=fn+2b>=fn+1
f
n
f_n
fn为Fibonacci数列的第n项。
这里可以用数学归纳法证明:
当第n步满足考虑(n+1)时,
a
n
+
1
=
⌊
a
n
+
1
b
n
+
1
⌋
a
n
+
b
n
>
=
⌊
a
n
+
1
b
n
+
1
⌋
f
n
+
2
+
f
n
+
1
>
=
f
n
+
2
+
f
n
+
1
=
f
n
+
3
a_{n+1}=\lfloor \frac{a_{n+1}}{b_{n+1}} \rfloor a_n+b_n>=\lfloor \frac{a_{n+1}}{b_{n+1}} \rfloor f_{n+2}+f_{n+1}>=f_{n+2}+f_{n+1}=f_{n+3}
an+1=⌊bn+1an+1⌋an+bn>=⌊bn+1an+1⌋fn+2+fn+1>=fn+2+fn+1=fn+3
下面只需要考虑Fibonacci的第n项是多少就可以了,如果学过矩阵乘法或者求矩阵特征向量特征根的话那就很容易了,如果没有的话可以去学一学,这里直接给出通项。
f
n
=
(
1
+
5
2
)
n
−
(
1
−
5
2
)
n
5
f_n=\frac{(\frac{1+\sqrt{5}}{2})^n-(\frac{1-\sqrt{5}}{2})^n}{\sqrt{5}}
fn=5(21+5)n−(21−5)n
显然
f
n
f_n
fn和
n
n
n是指数关系,即
f
n
=
a
n
,
a
>
1
f_n=a^n,\ a>1
fn=an, a>1
所以由
b
n
≈
f
n
+
1
b_n\approx f_{n+1}
bn≈fn+1可以得到,
n
≈
log
a
b
n \approx \log_a{b}
n≈logab
以上为辗转相除的复习。
下面考虑这样一个问题,即解决裴蜀定理,已知a,b
a
x
+
b
y
=
g
c
d
(
a
,
b
)
ax+by=gcd(a,b)
ax+by=gcd(a,b)
求一组整数解x, y。
考虑辗转相除法:
边界条件:
a
x
(
n
)
+
0
⋅
y
(
n
)
=
g
c
d
(
a
,
0
)
=
a
ax^{(n)}+0\cdot y^{(n)}=gcd(a,0)=a
ax(n)+0⋅y(n)=gcd(a,0)=a
显然有一组解:
x
(
n
)
=
1
,
y
(
n
)
=
0
x^{(n)}=1,\ y^{(n)}=0
x(n)=1, y(n)=0
第一层:
a
x
(
k
)
+
b
y
(
k
)
=
g
c
d
(
a
,
b
)
ax^{(k)}+by^{(k)}=gcd(a,b)
ax(k)+by(k)=gcd(a,b)
第二层:
b
x
(
k
+
1
)
+
r
y
(
k
+
1
)
=
g
c
d
(
b
,
r
)
,
a
≡
r
m
o
d
b
bx^{(k+1)}+ry^{(k+1)}=gcd(b,r),\ a \equiv r \mod b
bx(k+1)+ry(k+1)=gcd(b,r), a≡rmodb
有
g
c
d
(
a
,
b
)
=
g
c
d
(
b
,
r
)
gcd(a,b)=gcd(b,r)
gcd(a,b)=gcd(b,r), 和上面两式结合有:
a
x
(
k
)
+
b
y
(
k
)
=
b
x
(
k
+
1
)
+
r
y
(
k
+
1
)
ax^{(k)}+by^{(k)}=bx^{(k+1)}+ry^{(k+1)}
ax(k)+by(k)=bx(k+1)+ry(k+1)
r
=
a
−
⌊
a
b
⌋
b
r=a-\lfloor \frac{a}{b}\rfloor b
r=a−⌊ba⌋b
a
x
(
k
)
+
b
y
(
k
)
=
b
x
(
k
+
1
)
+
(
a
−
⌊
a
b
⌋
b
)
⋅
y
(
k
+
1
)
ax^{(k)}+by^{(k)}=bx^{(k+1)}+(a-\lfloor \frac{a}{b}\rfloor b)\cdot y^{(k+1)}
ax(k)+by(k)=bx(k+1)+(a−⌊ba⌋b)⋅y(k+1)
上式左右两边相等可以得到:
x
(
k
)
=
y
(
k
+
1
)
y
(
k
)
=
x
(
k
+
1
)
−
⌊
a
b
⌋
y
(
k
+
1
)
\begin{aligned} x^{(k)}&=y^{(k+1)}\\ y^{(k)}&=x^{(k+1)}-\lfloor \frac{a}{b}\rfloor y^{(k+1)} \end{aligned}
x(k)y(k)=y(k+1)=x(k+1)−⌊ba⌋y(k+1)
于是就得到了一个递推式,结合边界条件就可以得到解。
void Ex_gcd(int a, int b, int &x, int &y)
{
if(b == 0)
{
x = 1;
y = 0;
return;
}
int x1, y1;
Ex_gcd(b, a%b, x1, y1);
x = y1;
y = x1-(a/b)*y1;
}
然后求到 x ( 1 ) , y ( 1 ) x^{(1)},\ y^{(1)} x(1), y(1),之后可以通过加上若干个 a p + b q = 0 , a > 0 a p +b q=0,\ a>0 ap+bq=0, a>0,那么x的最小正整数解就是 x ≡ x ( a ) m o d p x\equiv x^{(a)}\mod p x≡x(a)modp。
5. 中国剩余定理
韩信点兵:3个人一排剩2个,5个人一排剩3个,7个人一排剩2个,问有几个人?
答案233个或23个
⋯
\cdots
⋯!
问题的形式化:
x
≡
a
1
m
o
d
m
1
x
≡
a
2
m
o
d
m
2
…
x
≡
a
k
m
o
d
m
k
\begin{aligned} x &\equiv a_1 \mod m_1\\ x &\equiv a_2 \mod m_2\\ &\dots\\ x &\equiv a_k \mod m_k \end{aligned}
xxx≡a1modm1≡a2modm2…≡akmodmk
任意两个
m
i
,
m
j
m_i,\ m_j
mi, mj, 需要满足
(
m
i
,
m
j
)
=
1
(m_i,m_j)=1
(mi,mj)=1。
构造一个
M
=
m
1
m
2
…
m
k
M=m_1m_2\dots m_k
M=m1m2…mk
再定义一个
M
1
=
M
m
1
M
2
=
M
m
2
⋯
M
k
=
M
m
k
\begin{aligned} M_1&=\frac{M}{m_1}\\ M_2&=\frac{M}{m_2}\\ &\cdots\\ M_k&=\frac{M}{m_k}\\ \end{aligned}
M1M2Mk=m1M=m2M⋯=mkM
对于
M
i
M_i
Mi, 可以求一个
t
i
t_i
ti,满足
M
i
t
i
≡
1
m
o
d
m
i
M_i t_i \equiv 1\mod m_i
Miti≡1modmi。
这时候就构造出来了!
x
=
∑
i
=
1
k
a
i
t
i
M
i
x=\sum_{i=1}^k a_it_iM_i
x=i=1∑kaitiMi
x
x
x显然是上述同余方程组的解。
其中唯一有问题的就是其中求
t
i
t_i
ti,就是求一个整数a关于p的倒数,现有
(
a
,
p
)
=
1
(a,p)=1
(a,p)=1,
(
a
⋅
x
)
%
p
=
1
(a\cdot x)\%p=1
(a⋅x)%p=1可以转化成
a
⋅
x
+
p
⋅
y
=
1
=
(
a
,
p
)
a\cdot x+p\cdot y=1=(a,p)
a⋅x+p⋅y=1=(a,p)
于是就可以用扩展欧几里得算法来求
x
x
x和
y
y
y了,当然我们只需要求
x
x
x。
6. 威尔逊定理
p
是
质
数
⇔
(
p
−
1
)
!
≡
p
−
1
m
o
d
p
p是质数 \Leftrightarrow (p-1)!\equiv p-1 \mod p
p是质数⇔(p−1)!≡p−1modp
必要性显然
充分性给一个用费马小定理的证明,
p
≥
3
p\geq 3
p≥3且p是质数:
f
(
x
)
=
(
x
−
1
)
⋅
(
x
−
2
)
…
(
x
−
(
p
−
1
)
)
=
x
p
−
1
+
(
1
+
2
+
⋯
+
p
−
1
)
x
p
−
2
+
⋯
+
(
p
−
1
)
!
\begin{aligned} f(x)&=(x-1)\cdot (x-2) \dots (x-(p-1)) \\ &=x^{p-1}+(1+2+\dots +p-1)x^{p-2}+\dots+(p-1)! \end{aligned}
f(x)=(x−1)⋅(x−2)…(x−(p−1))=xp−1+(1+2+⋯+p−1)xp−2+⋯+(p−1)!
注意这里满足f(x)=0的根为
1
∼
(
p
−
1
)
1\sim(p-1)
1∼(p−1)
定义
g
(
x
)
=
x
p
−
1
−
1
g(x)=x^{p-1}-1
g(x)=xp−1−1
根据费马小定理,满足
g
(
x
)
≡
0
m
o
d
p
g(x) \equiv 0 \mod p
g(x)≡0modp的解也是
1
∼
(
p
−
1
)
1\sim(p-1)
1∼(p−1)
所以对于任意的
x
x
x,满足
h
(
x
)
=
f
(
x
)
−
g
(
x
)
≡
0
m
o
d
p
h(x)=f(x)-g(x)\equiv 0 \mod p
h(x)=f(x)−g(x)≡0modp
但是考虑到 h ( x ) h(x) h(x)的最高此项是 x ( p − 2 ) x^(p-2) x(p−2)这一项,所以方程 h ( x ) ≡ 0 m o d p h(x)\equiv 0\mod p h(x)≡0modp最多有 ( p − 2 ) (p-2) (p−2)个解,因此 h ( x ) h(x) h(x)只能恒等于0。
所以他的常数项
(
p
−
1
)
!
+
1
(p-1)!+1
(p−1)!+1必须满足
(
p
−
1
)
!
+
1
≡
0
m
o
d
p
(p-1)!+1\equiv 0 \mod p
(p−1)!+1≡0modp,这个式子就是威尔逊定理。
题目:hdu2973
Appendix
施工中 … \dots …