欧几里得
说在前面
数论学复习 Part 6。
然后再来一章CRT和组合数,就飞往概率,以此为跳板去向DP。
计划很美啊你。
P.S. 这么说来拉格朗日插值可以说是数论学复习的Part 0了啊。
有一个*龙门粗口*
的*这就是祖安人打招呼的方式*
博主在以前发了一篇*儒雅随和*
的博客,也是讲这个的,虽然写的很*祖安粗口*
,但证明还是可堪一看的,(反正是借鉴来的)。
为什么我还会记得多年前的我写博客的亚子呢?
更相减损术 辗转相减法
可半者半之,不可半者,副置分母、子之数,以少减多,更相减损,求其等也。以等数约之。
g c d ( a , b ) = g c d ( b , a − b ) gcd(a,b)=gcd(b,a-b) gcd(a,b)=gcd(b,a−b)。
int gcd(int a,int b)
{
if(a<b) swap(a,b);
return b?gcd(b,a-b):a;
}
再加上“可半者半之”。
int gcd(int a,int b)
{
if(a<b) swap(a,b);
if(a&1) a>>=1;
if(b&1) b>>=1;
return b?gcd(b,a-b):a;
}
P . S . 更 相 损 减 术 本 来 是 用 来 约 分 的 , 所 以 “ 可 半 者 半 之 ” 这 句 话 被 狭 义 理 解 为 分 子 分 母 都 是 偶 数 时 约 掉 2 。 而 我 纯 路 人 , 看 到 可 半 者 半 之 就 直 接 断 章 取 义 了 。 P.S. 更相损减术本来是用来约分的,所以“可半者半之”这句话被狭义理解为分子分母都是偶数时约掉2。\\ 而我纯路人,看到可半者半之就直接断章取义了。 P.S.更相损减术本来是用来约分的,所以“可半者半之”这句话被狭义理解为分子分母都是偶数时约掉2。而我纯路人,看到可半者半之就直接断章取义了。
这样的话,stein算法和辗转相减法一模一样。 ( 中 国 数 学 领 先 外 国 1700 年 ! ) \xcancel{(中国数学领先外国1700年!)} (中国数学领先外国1700年!)
原理是一个数 d d d它整除 a a a和 b b b的话,它就整除 a , b a,b a,b的任意线性组合即 d ∣ p a + q b ( p , q ∈ Z ) d\mid pa+qb~~~(p,q\in Z) d∣pa+qb (p,q∈Z)。
证明私以为完全不需要了。
欧几里得算法 辗转相除法
g
c
d
(
a
,
b
)
=
g
c
d
(
b
,
a
%
b
)
gcd(a,b)=gcd(b,a\%b)
gcd(a,b)=gcd(b,a%b)
模运算是什么?就是多次反复地减直到减不动。
就是多次调用上一个算法。
正确性就更不用赘述了。
int dcg(int a,int b)
{
return b?dcg(b,a%b):a;
}
贝祖(裴蜀)定理
对于任意整数
a
,
b
a,b
a,b,一定存在整数
x
,
y
x,y
x,y,使得
a
x
+
b
y
=
g
c
d
(
a
,
b
)
ax+by=gcd(a,b)
ax+by=gcd(a,b)。
特别的,如果
a
,
b
a,b
a,b互质,就一定存在整数
x
,
y
x,y
x,y满足
a
x
+
b
y
=
1
ax+by=1
ax+by=1。
设 g c d ( a , b ) = d gcd(a,b)=d gcd(a,b)=d, a = p d , b = q d a=pd,b=qd a=pd,b=qd,则 a x + b y = g c d ( a , b ) ⟺ p x + q y = 1 ax+by=gcd(a,b)\iff px+qy=1 ax+by=gcd(a,b)⟺px+qy=1。易知 g c d ( p , q ) = 1 gcd(p,q)=1 gcd(p,q)=1。
也就是说把所有一般命题转到了“特别的”命题上来。
怎么证明存在性问题?简单啊,给出一组 ( x , y ) (x,y) (x,y)不就好了吗?
原式 ⟺ p x ≡ 1 m o d q \iff px\equiv 1\mod q ⟺px≡1modq
就是求p关于q的一个逆元,这个逆元的存在性我已经在之前不用贝祖证明出来了(1.1),现在就不再赘述一次。
P.S.换一个等价命题应该会证得舒服点,比如 a c ≡ b c m o d p , ( c , p ) = 1 → a ≡ b m o d p ac\equiv bc\mod p,(c,p)=1\to a\equiv b \mod p ac≡bcmodp,(c,p)=1→a≡bmodp。
拓展欧几里得算法
拓展欧几里得算法能够在辗转相除的同时求出一组 x , y x,y x,y使得 a x + b y = g c d ( a , b ) ax+by=gcd(a,b) ax+by=gcd(a,b)。
怎么在辗转相除的时候求呢?我们要看
g
c
d
(
b
,
a
%
b
)
gcd(b,a\%b)
gcd(b,a%b)是吧?
我们设已经辗转相除求出了
b
x
0
+
(
a
%
b
)
y
0
=
g
c
d
(
b
,
a
%
b
)
bx_0+(a\%b)y_0=gcd(b,a\%b)
bx0+(a%b)y0=gcd(b,a%b),然后试图用
x
0
,
y
0
x_0,y_0
x0,y0递推出
x
,
y
x,y
x,y。
因为
g
c
d
(
a
,
b
)
=
g
c
d
(
b
,
a
%
b
)
gcd(a,b)=gcd(b,a\%b)
gcd(a,b)=gcd(b,a%b),所以有
a
x
+
b
y
=
b
x
0
+
(
a
%
b
)
y
0
ax+by=bx_0+(a\%b)y_0
ax+by=bx0+(a%b)y0。设
a
=
k
b
+
r
a=kb+r
a=kb+r,则
原
方
程
⟺
(
k
b
+
r
)
x
+
b
y
=
b
x
0
+
r
y
0
⟺
b
(
k
x
+
y
)
+
r
x
=
b
x
0
+
r
y
0
原方程\iff (kb+r)x+by=bx_0+ry_0\iff b(kx+y)+rx=bx_0+ry_0
原方程⟺(kb+r)x+by=bx0+ry0⟺b(kx+y)+rx=bx0+ry0。
然后随便多项式恒等定理一下就得到
{
k
x
+
y
=
x
0
x
=
y
0
⇒
{
x
=
y
0
y
=
x
0
−
k
y
0
=
x
0
−
⌊
a
b
⌋
y
0
\begin{cases}kx+y=x_0\\x=y_0\end{cases}\Rarr\begin{cases}x=y_0\\ y=x_0-ky_0=x_0-\lfloor\frac{a}{b}\rfloor y_0 \end{cases}
{kx+y=x0x=y0⇒{x=y0y=x0−ky0=x0−⌊ba⌋y0。
然后到最后 b = 0 , a = g c d b=0,a=gcd b=0,a=gcd的时候,有 x k = 1 , y k = 0 x_k=1,y_k=0 xk=1,yk=0。
int exgcd(int a,int b,int &x,int &y)
{
if(!b) {x=1,y=0; return a;}
int w=exgcd(b,a%b,y,x);
y-=x*(a/b);
return w;
}
或者
void exgcd(int a,int b,int &d,int &x,int &y)
{
if(!b) {x=1,y=0,d=a; return ;}
exgcd(b,a%b,d,y,x),y-=x*(a/b);
}
逆元
定义
除法怎么取模?
小数分数怎么取模?整除、整数的概念都没有了,你怎么取模?
那怎么除法呢?
怎么规避小数分数呢?
5
2
=
2.5
\frac{5}{2}=2.5
25=2.5的话,
5
=
2
∗
2.5
5=2*2.5
5=2∗2.5。
所以乘法就行了。
我们如果说一个数
a
a
a关于
p
p
p的逆元是
a
−
1
a^{-1}
a−1的话,就等价于定义
x
a
m
o
d
p
=
x
a
−
1
m
o
d
p
\frac{x}{a}\mod p=xa^{-1}\mod p
axmodp=xa−1modp。
要求
a
×
a
−
1
≡
1
m
o
d
p
a\times a^{-1}\equiv 1\mod p
a×a−1≡1modp。
这个逆元存在的前提上文也有说, a , p a,p a,p要互质。
求法
法一
如果
p
p
p是质数的话,我们就有费马小定理,
a
p
−
1
≡
1
m
o
d
p
a^{p-1}\equiv 1\mod p
ap−1≡1modp。此时
a
a
a的逆元显然就是
a
×
a
p
−
2
≡
1
m
o
d
p
a\times a^{p-2}\equiv 1\mod p
a×ap−2≡1modp。
这个东西据说还叫蒙哥马利快速幂模。
法二
另外一种方法就是用exgcd。
exgcd(a,b,&x,&y)得到的x就是a关于b的逆元,y就是b关于a的逆元。
筛法
给一个数p,递推地求逆元,求出一个范围内所有数关于p的逆元。
那么p肯定是质数或者相对是质数了。
现在正在求 a a a关于 p p p的逆元,设 p = k a + r p=ka+r p=ka+r,则有 k a + r ≡ 0 ( m o d p ) ka+r\equiv0 \pmod p ka+r≡0(modp),设 a a a的逆元为 a − 1 a^{-1} a−1, r r r的逆元是 r − 1 r^{-1} r−1,在两边同时乘以 a − 1 r − 1 a^{-1}r^{-1} a−1r−1,则有 k r − 1 + a − 1 ≡ 0 ( m o d p ) ⟺ a − 1 ≡ − k r − 1 ≡ − ⌊ p a ⌋ ( p m o d a ) − 1 ( m o d p ) kr^{-1}+a^{-1}\equiv 0\pmod p\iff a^{-1}\equiv -kr^{-1}\equiv -\lfloor \frac{p}{a}\rfloor(p\mod a)^{-1}\pmod p kr−1+a−1≡0(modp)⟺a−1≡−kr−1≡−⌊ap⌋(pmoda)−1(modp)。
inv[0]=inv[1]=1;
for(int i=2;i<=N;i++) inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
解模线性方程
a x + b y = c ax+by=c ax+by=c。
首先如果
g
c
d
(
a
,
b
)
∤
c
gcd(a,b)\nmid c
gcd(a,b)∤c的话,肯定无解,因为左边必然是
g
c
d
(
a
,
b
)
gcd(a,b)
gcd(a,b)的倍数。
如果
g
c
d
(
a
,
b
)
∣
c
gcd(a,b)\mid c
gcd(a,b)∣c的话,设
c
=
k
×
g
c
d
(
a
,
b
)
c=k\times gcd(a,b)
c=k×gcd(a,b),那么我们跑一次扩欧,得到
a
x
0
+
b
y
0
=
g
c
d
(
a
,
b
)
ax_0+by_0=gcd(a,b)
ax0+by0=gcd(a,b)的一组解
(
x
0
,
y
0
)
(x_0,y_0)
(x0,y0),然后再乘上
k
k
k就搞定了。
{
x
=
k
x
0
y
=
k
y
0
\begin{cases}x=kx_0\\y=ky_0\end{cases}
{x=kx0y=ky0
如果想要求最小正整数解的话,则就 ( x % p + p ) % p (x\%p+p)\%p (x%p+p)%p就是了。
a x ≡ b m o d p ax\equiv b \mod p ax≡bmodp。
和上面那个差不多。