数论知识点总结
1. g c d 1.gcd 1.gcd(最大公约数)
对于给出的两个数
a
,
b
a,b
a,b,我们可以用欧几里得算法来计算最大公约数。欧几里得算法的精髓就在于下面这个公式:
g
c
d
(
a
,
b
)
=
g
c
d
(
b
,
a
gcd(a,b)=gcd(b,a
gcd(a,b)=gcd(b,a%
b
)
b)
b)
证明:
已知:
g
c
d
(
a
,
b
)
∣
a
gcd(a,b)|a
gcd(a,b)∣a并且
g
c
d
(
a
,
b
)
∣
b
gcd(a,b)|b
gcd(a,b)∣b,设
a
a
a%
b
=
r
b=r
b=r,则
a
=
r
+
k
b
a=r+kb
a=r+kb,故
r
=
a
−
k
b
r=a-kb
r=a−kb,根据同余关系可得:
r
r
r%
g
c
d
(
a
,
b
)
=
0
gcd(a,b)=0
gcd(a,b)=0,因此
g
c
d
(
a
,
b
)
=
g
c
d
(
b
,
a
gcd(a,b)=gcd(b,a
gcd(a,b)=gcd(b,a%
b
)
b)
b)
code:
int gcd(int a,int b){
return b?gcd(b,a%b):a
}
2. e x g c d 2.exgcd 2.exgcd(扩展欧几里得算法)
扩展欧几里得算法是用于求解
a
x
+
b
y
=
g
c
d
(
a
,
b
)
ax+by=gcd(a,b)
ax+by=gcd(a,b)的一组解的算法。
根据欧几里得算法我们可知:
g
c
d
(
a
,
b
)
=
g
c
d
(
b
,
a
gcd(a,b)=gcd(b,a
gcd(a,b)=gcd(b,a%
b
)
b)
b)
我们假设
x
1
,
y
1
x1,y1
x1,y1是满足条件的一组解
那么
a
x
1
+
b
y
1
=
g
c
d
(
a
,
b
)
ax1+by1=gcd(a,b)
ax1+by1=gcd(a,b)
而
g
c
d
(
a
,
b
)
=
g
c
d
(
b
,
a
gcd(a,b)=gcd(b,a
gcd(a,b)=gcd(b,a%
b
)
b)
b)
故
a
x
1
+
b
y
1
=
b
x
2
+
a
ax1+by1=bx2+a
ax1+by1=bx2+a%
b
y
2
by2
by2
而
a
a
a%
b
=
a
−
a
/
b
∗
b
b=a-a/b\ast b
b=a−a/b∗b
因而
a
x
1
+
b
y
1
=
b
x
2
+
a
y
2
−
a
/
b
∗
b
y
2
=
a
y
2
+
b
∗
(
x
2
−
a
/
b
∗
y
2
)
ax1+by1=bx2+ay2-a/b\ast by2=ay2+b*(x2-a/b\ast y2)
ax1+by1=bx2+ay2−a/b∗by2=ay2+b∗(x2−a/b∗y2)
那么我们就得到了一组合法的
x
1
,
y
1
x1,y1
x1,y1的解:
x
1
=
y
2
,
y
1
=
x
2
−
a
/
b
∗
y
2
x1=y2,y1=x2-a/b\ast y2
x1=y2,y1=x2−a/b∗y2
也就是我们递归下去即可。当
b
=
0
b=0
b=0的时候我们就可以发现
x
=
1
,
y
=
0
x=1,y=0
x=1,y=0是合法的
这是我们再返回
x
=
1
,
y
=
0
x=1,y=0
x=1,y=0。最后就一直会回溯下去,得到我们的
x
1
,
y
1
x1,y1
x1,y1
void exgcd(int a,int b){
if(!b){
x=1,y=0;
return ;
}
exgcd(b,a%b)
int temp=x;
x=y;y=temp-a/b*x;
}
但是如果要求
a
x
+
b
y
=
g
c
d
(
a
,
b
)
ax+by=gcd(a,b)
ax+by=gcd(a,b)的最小整数解的时候,我们就要对
x
x
x批量的加上
b
b
b的倍数,但是这不会影响最终的结果。
因为
a
x
+
b
y
+
k
a
b
−
k
a
b
=
a
(
x
+
k
b
)
+
b
∗
(
y
−
k
a
)
ax+by+kab-kab=a(x+kb)+b*(y-ka)
ax+by+kab−kab=a(x+kb)+b∗(y−ka),这样依旧是合法的。
因此我们直接让
x
=
(
x
x=(x
x=(x%
b
+
b
)
b+b)
b+b)%
b
b
b即为最终的答案。
3. 3. 3.逆元
对于
a
a
a和
m
m
m,如果
a
x
≡
1
(
m
o
d
m
)
ax\equiv1(modm)
ax≡1(modm),那么称
x
x
x是
a
a
a在
m
m
m下的逆元。
那么我们该怎么求解逆元呢?我们将逆元的等式转化一下:
a
x
+
m
y
=
1
ax+my=1
ax+my=1
由于
a
x
+
m
y
=
k
ax+my=k
ax+my=k有解当且仅当
k
k
k%
g
c
d
(
a
,
m
)
=
0
gcd(a,m)=0
gcd(a,m)=0的时候有解,说明
g
c
d
(
a
,
m
)
=
1
gcd(a,m)=1
gcd(a,m)=1
那么我们直接用扩展欧几里得求解即可。
int x,y;
void exgcd(int a,int b){
if(!b){
x=1,y=0;
return ;
}
exgcd(b,a%b)
int temp=x;
x=y;y=temp-a/b*x;
}
int inv(int a,int m){//a在m下的逆元
exgcd(a,m);
return (x%m+m)%m;
}
逆元一般是用在除法取模上面,如 ( a / b ) (a/b) (a/b)% m m m即为 a a a% m ∗ i n v ( b , m ) m\ast inv(b,m) m∗inv(b,m)
4. 4. 4.埃拉托斯特尼筛法
埃拉托斯特尼筛法是一个复杂度为
n
l
n
n
l
n
n
nlnnlnn
nlnnlnn的筛法。
当选中一个数为素数的时候,就把以这个数为因子的数全部筛掉即可。
const int N=1e6+100;
vector<int> pr;
bool vis[N];
void seive(){
vis[0]=vis[1]=1;
for(int i=2;i<=N-10;i++){
if(!vis[i]){
pr.push_back(i);
for(int j=2*i;j<=N-10;j+=i) vis[j]=1;
}
}
}
5. 5. 5.费马小定理
假设
a
a
a是一个整数,
p
p
p是一个质数,那么
a
p
−
a
a^p-a
ap−a是
p
p
p的倍数
即
a
p
≡
a
(
m
o
d
p
)
a^p\equiv a(modp)
ap≡a(modp),如果
a
a
a不是
p
p
p的倍数,这个定理也可以写成:
a
p
−
1
≡
1
(
m
o
d
p
)
a^{p-1}\equiv1(modp)
ap−1≡1(modp)
6. 6. 6.线性同余方程求解
形如
a
x
≡
b
(
m
o
d
m
)
ax\equiv b(modm)
ax≡b(modm)即为线性同余方程。
将线性同余方程变形后即可得到:
a
x
+
m
y
=
b
ax+my=b
ax+my=b
只有当
b
b
b%
g
c
d
(
a
,
m
)
=
0
gcd(a,m)=0
gcd(a,m)=0时该方程才有解。
我们先利用扩展欧几里得算法求出
a
x
+
m
y
=
g
c
d
(
a
,
m
)
ax+my=gcd(a,m)
ax+my=gcd(a,m)的一组解
(
x
0
,
y
0
)
(x0,y0)
(x0,y0),那么
x
=
x
0
∗
(
b
/
g
c
d
(
a
,
m
)
)
x=x0*(b/gcd(a,m))
x=x0∗(b/gcd(a,m))%
m
m
m
即为原方程的一组解。
7. 7. 7.欧拉函数
欧拉函数即为小于
n
n
n的数中与
n
n
n互质的数的个数
比如
φ
(
8
)
=
4
\varphi(8)=4
φ(8)=4
欧拉函数的通式为:
φ
(
x
)
=
x
(
1
−
1
p
1
)
(
1
−
1
p
2
)
.
.
.
(
1
−
1
p
n
)
\varphi(x)=x(1-\frac{1}{p1})(1-\frac{1}{p2})...(1-\frac{1}{pn})
φ(x)=x(1−p11)(1−p21)...(1−pn1)
其中
p
1
,
p
2
,
.
.
.
p
n
p1,p2,...pn
p1,p2,...pn为
x
x
x的质因数。