往期回顾
裴蜀定理
内容
裴蜀定理是指方程
a
x
+
b
y
=
m
ax + by = m
ax+by=m当且仅当m是a和b的最大公因数d的倍数时,方程有整数解
特别的,只有a和b互质时,
a
x
+
b
y
=
1
ax + by = 1
ax+by=1才有整数解
证明
设存在
x
,
y
x,y
x,y,满足
a
x
+
b
y
ax + by
ax+by为正数最小值
d
d
d。任选
m
,
n
m,n
m,n不等于
x
,
y
x,y
x,y,此时
a
m
+
b
n
am + bn
am+bn为
e
e
e,则
e
≥
d
e≥d
e≥d。
e
=
p
×
d
+
r
e=p \times d+r
e=p×d+r(
p
p
p为商,
r
r
r是余数),则
r
<
d
r<d
r<d
那么
r
=
e
−
p
×
d
=
a
m
+
b
n
−
p
×
(
a
x
+
b
y
)
=
(
m
−
p
x
)
×
a
+
(
n
−
p
y
)
×
b
r=e-p \times d=am+bn-p \times (ax+by)=(m-px) \times a+(n-py)\times b
r=e−p×d=am+bn−p×(ax+by)=(m−px)×a+(n−py)×b
则有
m
−
p
x
m-px
m−px和
n
−
p
y
n-py
n−py满足比d更小的值
r
r
r,
r
r
r只能为0
所以
e
e
e是
d
d
d的倍数
设
g
c
d
(
a
,
b
)
=
l
,
a
=
s
l
,
b
=
t
l
gcd(a,b)=l,a=sl,b=tl
gcd(a,b)=l,a=sl,b=tl,则
d
=
l
(
s
x
+
t
y
)
d=l(sx+ty)
d=l(sx+ty),所以
d
d
d一定是
g
c
d
(
a
,
b
)
gcd(a,b)
gcd(a,b)的倍数
综上可知,
d
d
d为
g
c
d
(
a
,
b
)
gcd(a,b)
gcd(a,b)的倍数,
e
e
e为
d
d
d的倍数
构造
构造有很多,而扩展欧几里得算法的解就是其中之一。
详情看数论(一),这里不再构造
欧拉定理
欧拉函数
欧拉函数,即 φ ( n ) φ(n) φ(n),指1~ n n n中与 n n n互质的数的个数
欧拉函数的计算
φ
(
1
)
=
1
φ(1)=1
φ(1)=1
如果
i
i
i是质数,那么
φ
(
i
)
=
i
−
1
φ(i)=i-1
φ(i)=i−1
如果
i
i
i是合数,那么设
i
=
∏
i
=
1
m
p
i
k
i
i=\prod^{m}_{i=1}p_i^{k_i}
i=∏i=1mpiki且
p
i
p_i
pi为质数,则
φ
(
i
)
=
n
×
∏
i
=
1
m
p
i
−
1
p
i
φ(i)=n\times \prod^{m}_{i=1} \frac{p_i-1}{p_i}
φ(i)=n×∏i=1mpipi−1
如果只求一个数的欧拉函数,可以在分解质因数中求
如果求线性的欧拉函数,则可以在线性筛中求
欧拉定理
若 g c d ( a , m ) = 1 gcd(a,m)=1 gcd(a,m)=1,那么 a φ ( m ) ≡ 1 ( m o d m ) a^{φ(m)} \equiv1 (\mod m) aφ(m)≡1(modm)
乘法逆元
我们知道,
a
×
a
−
1
≡
1
(
m
o
d
b
)
a\times a^{-1}\equiv 1(\mod b)
a×a−1≡1(modb)
那么如果给定
a
,
b
a,b
a,b,怎么求
x
=
a
−
1
x=a^{-1}
x=a−1呢
扩展欧几里得算法求逆元
我们知道,扩展欧几里得算法求的是
a
x
+
b
y
=
g
c
d
(
a
,
b
)
ax+by=gcd(a,b)
ax+by=gcd(a,b)的解
这和乘法逆元又有什么关系呢?
我们先来看看条件吧。
a
x
≡
1
(
m
o
d
b
)
ax \equiv1(\mod b)
ax≡1(modb)一定有解,说明了
a
x
+
b
y
=
g
c
d
(
a
,
b
)
≡
1
(
m
o
d
b
)
ax+by=gcd(a,b)\equiv 1(\mod b)
ax+by=gcd(a,b)≡1(modb)
而
1
≤
g
c
d
(
a
,
b
)
≤
b
1 \le gcd(a,b) \le b
1≤gcd(a,b)≤b,因此
g
c
d
(
a
,
b
)
=
1
gcd(a,b)=1
gcd(a,b)=1
因此,我们用扩展欧几里得算法可以求出
a
x
+
b
y
=
1
ax+by=1
ax+by=1的解
在这种情况下,显然
a
x
≡
1
(
m
o
d
b
)
ax \equiv1(\mod b)
ax≡1(modb)
但别忘了现在的
x
x
x可能不是正整数,也不一定是最小的解,因此我们要的答案是
(
x
%
b
+
b
)
%
b
(x\%b+b)\%b
(x%b+b)%b
懂了吗?
奉上代码一份:
#include<iostream>
using namespace std;
long long x,y;
void gcd(long long a,long long b){
if(!b){
x=1,y=0;
return ;
}
gcd(b,a%b);
long long t=x;
x=y,y=t-a/b*y;
}
int main(){
long long a,b;
cin>>a>>b;
gcd(a,b);
x=(x%b+b)%b;
cout<<x;
return 0;
}
噢,对了,大家还可以顺便把这题给切了,刷个绿题谁不愿意呢?
欧拉定理求逆元
知道我这次为什么必须要讲欧拉定理了吧。
As we all know,
a
φ
(
b
)
≡
1
(
m
o
d
b
)
a^{φ(b)} \equiv1 (\mod b)
aφ(b)≡1(modb)
∴
a
×
a
φ
(
b
)
−
1
≡
1
(
m
o
d
b
)
∴a \times a^{φ(b)-1} \equiv 1(\mod b)
∴a×aφ(b)−1≡1(modb)
因此,我们要求的乘法逆元就是
a
φ
(
b
)
−
1
%
b
a^{φ(b)-1} \% b
aφ(b)−1%b
至于怎么求,快速幂嘛,对吧,反正我也懒得写了嘿嘿
当然如果
b
b
b是质数,我们用费马小定理也是得出一样的结论的
线性求逆元
如果要求1~n的逆元了,怎么样才能最快?
我想,最缓(xun)慢(su)的做法就是暴力了。
我们可以来找找逆元之间的关系
⌊
p
a
⌋
×
a
=
p
−
(
p
%
a
)
\lfloor \frac{p}{a} \rfloor\times a=p-(p\%a)
⌊ap⌋×a=p−(p%a)
⌊
p
a
⌋
×
a
≡
−
(
p
%
a
)
(
m
o
d
p
)
\lfloor \frac{p}{a} \rfloor\times a\equiv -(p\%a) (\mod p)
⌊ap⌋×a≡−(p%a)(modp)
a
≡
−
(
p
%
a
)
⌊
p
a
⌋
(
m
o
d
p
)
a\equiv\frac{-(p\%a)}{\lfloor \frac{p}{a} \rfloor} (\mod p)
a≡⌊ap⌋−(p%a)(modp)
a
−
1
≡
⌊
p
a
⌋
−
(
p
%
a
)
(
m
o
d
p
)
a^{-1}\equiv\frac{\lfloor \frac{p}{a} \rfloor}{-(p\%a)} (\mod p)
a−1≡−(p%a)⌊ap⌋(modp)
a
−
1
≡
−
⌊
p
a
⌋
×
(
p
%
a
)
−
1
(
m
o
d
p
)
a^{-1}\equiv -\lfloor \frac{p}{a} \rfloor\times (p\%a)^{-1} (\mod p)
a−1≡−⌊ap⌋×(p%a)−1(modp)
所以我们就可以通过这个来计算线性上的逆元了
inv[1]=1;
for(int i=2;i<=n;i++){
inv[i]=(long long)(b-b/i)*inv[b%i]%b
}
今天要不就到这吧。