欧拉定理和欧拉函数
欧拉函数:
定义式:
φ(x)=i=1∑x[gcd(i,x)=1]
根据定义可证欧拉函数是积性函数。
- 筛法
很容易得出 φ(pk)=pk−pk−1 (p∈P) 。
进而得出 φ(pk)=p⋅φ(pk−1) (p∈P) 。
那么有当 x=p⋅y(p∈P) 时有
φ(p⋅y)=φ(p)⋅φ(y)=(p−1)⋅φ(y) (gcd(p,y)=1)
φ(p⋅y)=φ(pk⋅pk−1y)=φ(pk)⋅φ(pk−1y)=p⋅φ(pk−1)⋅φ(pk−1y)=p⋅φ(y)
(gcd(p,y)=1,gcd(pk,pk−1y)=1)
运用以上两个公式就可以线性筛了。
或者可以变换成各种形式用其他筛法。
- 推式子
常用的式子:
φ(x)=i=1∏k(piai−piai−1)=x⋅i=1∏kpipi−1 (∀pi∈P;i=1∏kpiai=x;i=j,pi=pj)
欧拉定理:
ifgcd(a,p)=1, aφ(p)≡1(mod p)
我有一个伪证:由于 ai 与 p 互质,故在 [0,p−1] 中有 p−φ(p) 个数是不会出现的,其他数构成周期为 φ(p) 的循环,故 aφ(p)+1≡a 。
当然,这是错的,只能帮助理解。现在懒得学证明了。
欧拉定理可以用来求逆元。但我们更多情况下还是用费马小定理和扩展欧几里得算法求。
逆元:
当 a,p 互质时,存在唯一的 b (mod p) 使得 a⋅b≡1 (mod p) 。记 b 为 a1 或 a−1 。
证明还不会。
欧拉定理求逆元: a−1≡aφ(p)−1 (mod p) 。
可以用线性筛和快速幂求。
费马小定理:
欧拉定理中,当 p∈P 时, ap−1≡1 (mod p) 。
费马小定理求逆元十分常用。当题目给的模数是一个很大的质数时经常用费马小定理。
a−1≡ap−2 (mod p) (p∈P) 。
一个快速幂就好了。
欧几里得算法和扩展欧几里得算法:
重要的公式:
gcd(a,b)=gcd(b,a mod b)
证明:令 gcd(a,b)=d ,则 a=x⋅d , b=y⋅d ,且 gcd(x,y)=1。
则 gcd(a,b)=gcd(x⋅d,y⋅d)=gcd(y⋅d,(x mod y)⋅d)=gcd(y⋅d,x⋅d mod y⋅d)=gcd(b,a mod b) 。
反复运用这一公式求出 gcd(a,b) 就是欧几里得算法。递归边界为 b=0 ,时间复杂度为 O(logmin(a,b)) 。
P.S. 用迭代法常数更小哦。
接下来看扩展欧几里得算法,简称扩欧。
对于一个方程 ax+by=gcd(a,b) 有无数个整数解。若求出解 (x0,y0) ,任意解 (x,y) 为:
x=x0+k⋅gcd(a,b)b, y=y0−k⋅gcd(a,b)a, k∈Z
任意解的推论是显然的。为什么存在 (x0,y0) 呢?因为我们可以反复用到之前的那个公式。当 b 最终等于 0 时,有一组解 x=1,y=0 使得 ax+by=gcd(a,b) 。我们递归回来的时候调整一下 x,y 就可以找到一组解了。
递归时,已经知道使 bx1+(a mod b)y1=gcd(a,b) 成立的 (x1,y1) 了。
我们需要知道使 ax2+by2=gcd(a,b) 成立的 (x2,y2) 。
打开前一个方程:
bx1+(a mod b)y1=gcd(a,b)
bx1+(a−⌊ba⌋⋅b)y1=gcd(a,b)
ay1+b(x1−⌊ba⌋⋅y1)=gcd(a,b)
解得 x2=y1, y2=x1−⌊ba⌋⋅y1 。
Code:
1 2 3 4 5 6 7 8 9 10 11 12
| int exgcd(int a,int b,int& x,int& y){ if (!b) return x=1,y=0,a; else{ int d=exgcd(b,a%b,y,x); y-=a/b*x; return d; } } void exgcd(int a,int b,int& x,int& y){ if (!b) return x=1,y=0,void(); else exgcd(b,a%b,y,x),y-=a/b*x,void(); }
|
扩展欧拉定理
我称之为降幂公式。
ab≡abmodφ(p)+φ(p) (mod p) (b≥φ(p))
证明以后再写。