数论-欧拉函数
欧拉函数
1、定义
欧拉函数\(\varphi(n)\)表示小于或等于\(n\)的整数中于\(n\)互质的数的数目。
2、欧拉函数值
欧拉函数具有积性(俺不会证),若\(n\)与\(m\)互素,则:
\[\varphi(m*n)=\varphi(m)*\varphi(n)
\]
所以,若\(n=p_1^{k_1}p_2^{k_2}...p_r^{k_r}\),则\(\varphi(n)=\varphi(p_1^{k_1})\varphi(p_2^{k_2})...\varphi(p_r^{k_r})\)
又:
\[\varphi(p^k)=p^k-p^{k-1}=p^{k-1}(p-1)
\]
即若n为素数p的k次,那么他的欧拉函数值为n减去1~n中p的倍数的个数。所以
\[\varphi(n)=\sum_i^r(p_i^{k_i-1}(p_i-1))=n\prod_{i=1}^r(\frac{p_i-1}{p_i})
\]
特殊的\(\varphi(1)=1\).
3、性质
(1)积性函数
(2)若\(xmod2=1,\)则\(\varphi(2*x)=\varphi(x)\)
(3)\(\sum_{d|n}\varphi(d)=n\)
(4)
\[\varphi(x)=\begin{cases} \varphi(x/p)·p & \text{gcd(x/p,p)=p}\\ \varphi(x/p)·(p-1) & \text{gcd(x/p,p)=1} \end{cases}
\]
4、代码实现
基于素因数分解的欧拉函数算法:
时间复杂度\(O(\sqrt n)\)
数据量较大可以考虑先来一发欧拉筛预处理。
ll eulerfunc(ll n){
ll sum=n;
for(ll i=2;i*i<=n;++i){
if(n%i==0) sum=sum/i*(i-1);
while(n%i==0) n/=i;
}
if(n!=1) sum=sum/n*(n-1);
return sum;
}
欧拉筛线性求欧拉函数:
时间复杂度为\(O(n)\)
该算法利用了性质(4),求n以内的欧拉函数值
void eulerfunc(ll n){
ph[1]=1;
cmt=0;
for(int i=2;i<=n;++i){
if(!isp[i]) {
p[++cnt]=i;
phi[i]=i-1;
}
for(int j=1;j<=cnt&&i*p[j]<=n;++j){
isp[i*p[j]]=1;
if(i%p[j]==0) {
phi[i*p[j]]=phi[i]*p[j];//gcd(x/p,p)=p
break;
}
else{
phi[i*p[j]]=phi[i]*(p[j]-1);//gcd(x/p,p)=1
}
}
}
}