[数论]欧拉函数&素数筛
Posted mogeko
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[数论]欧拉函数&素数筛相关的知识,希望对你有一定的参考价值。
一、欧拉函数
欧拉函数是小于x的整数中与x互质的数的个数,一般用φ(x)表示。
通式:
其中p1, p2……pn为x的所有质因数,x是不为0的整数。
- 比如x=12,拆成质因数为12=2*2*3,
- 12以内有1/2的数是2的倍数,那么有1-1/2的数不是2的倍数(1,3,5,7,9,11),
- 这6个数里又有1/3的数是3的倍数,
- 只剩下(1 - 1/2 - 1/3)的数既不是2的倍数,也不是3的倍数(1,5,7,11)。
- 这样剩下的12*(1 - 1/2 - 1/3)=4,即4个数与12互质,所以φ(12)=4。
证明:对于正整数x,
- 如果x=1,则 φ(1) = 1。
- 1与任何数(包括自身)都构成互质关系。
- 如果x是质数,则 φ(x)=x-1 。
- 质数与小于它的每一个数,都构成互质关系。比如5与1、2、3、4都构成互质关系。
- 如果n只有一个质因数p,即x = p^k(p为质数,k>=1),则φ(pk)=pk(1-1/p)=pk-pk-1 。
- 从1~x中,p的倍数共有x/p个,共占了1/p,则减去这些数后,还剩下x*(1-1/p)个。
- 可以看出,上一种情况是 k=1 时的特例。
- 如果n可以分解成两个互质的整数之积,即n = p1 * p2,则φ(x) = φ(p1 * p2) = φ(p1) * φ(p2)。
- 积性函数:若当m与n互质时,f(m?n)=f(m)?f(n) f(m*n)=f(m)*f(n)f(m?n)=f(m)?f(n),那么f是积性函数。
- 欧拉函数是积性函数(证明略)。
- 任意一个大于1的正整数,都可以写成一系列质数的积。
- 可以得到,φ(x) = φ(p1)*φ(p2)*...*φ(pn) = x(1-1/p1)*(1-1/p2)*...*(1-1/pn).
一些(目前不需要的)性质:
- 当n>2时,φ(n)是偶数。
- 小于n的数中,与n互质的数的总和为:φ(n) * n / 2 (n>1)。
- n的因数(包括1和它自己)的欧拉函数之和等于n。
- 若n为奇数时,φ(2n)=φ(n)。
- 对于任何两个互质的正整数a,n(n>2)有:a^φ(n)=1 mod n (恒等于)此公式即 欧拉定理。
- 当n=p 且 a与素数p互质(即:gcd(a,p)=1)则上式有: a^(p-1)=1 mod n (恒等于)此公式即 费马小定理。
求欧拉函数:
1.埃拉托斯特尼筛
求1~n所有数的欧拉函数:每次找到一个质数,就把它的倍数更新掉。复杂度大概是O(nlognlogn)。
void euler(int n){
for (int i=1;i<=n;i++) phi[i]=i;
for (int i=2;i<=n;i++)
if (phi[i]==i)for (int j=i;j<=n;j+=i)
phi[j]=phi[j]/i*(i-1);
2.欧拉筛
每次找到一个最小的因数(一定为质因数),求出x*(1 - 1/p)。复杂度为O(n)。
int euler(int n){
int res=n,a=n;
for(int i=2;i*i<=a;i++){
if(a%i==0){
res=res/i*(i-1);
while(a%i==0) a/=i;
}
}
if(a>1) res=res/a*(a-1);
return res;
}
对于x = p1^k * p2^m...,只需要求一次(1-p1)(1-p2)...就可以了,
为了保证每个质因数只被使用一次,通过以上的while循环把x中的p1除尽。
二、素数筛法
好困(我觉得这个写的挺好)
参考文章:
https://blog.csdn.net/liuzibujian/article/details/81086324
https://blog.csdn.net/paxhujing/article/details/51353672
以上是关于[数论]欧拉函数&素数筛的主要内容,如果未能解决你的问题,请参考以下文章