【学习笔记】欧拉函数
欧拉函数
欧拉函数 $\varphi(x) $ 等于在 \([1,x]\) 区间内和 \(x\) 互质的数的个数。
\(\varphi(x)\) 有个便于计算的公式,可以表示为:
\[\varphi(x)=x \times \prod_{p|x}(1-\frac{1}{p})
\]
其中 \(p\) 为素数。
ll phi(ll x){
ll f=x;
for(ll p=2;p*p<=x;p++){
if(x%p) continue;
f=f/p*(p-1);
while(!(x%p)) x/=p;
}
if(x>1) f=f/x*(x-1);
return f;
}
注:若 \(x\) 很大,要先除再乘,不然可能会爆 long long。
并且 \(\varphi(x)\) 是个积性函数,即若 \(p,q\) 互质,则有 \(\varphi(pq)=\varphi(p) \times \varphi(q)\)。另外还有两个重要的特点:
-
若 \(n \% k == 0\) 则有 \(\varphi(nk)=\varphi(n) \times k\)
-
若 \(n \% k != 0\) 则有 \(\varphi(nk)=\varphi(n) \times (k-1)\)
通过这些,可以 \(O(n)\) 筛素数的同时处理出每个 \(\varphi(i)\) 对应的值。
int phi[N],pr[N],cnt;
bool vis[N];
void getphi(){
phi[1]=1;
for(int i=2;i<=1e6;i++){
if(!vis[i]){
pr[++cnt]=i;
phi[i]=i-1;
}
for(int j=1;j<=cnt;j++){
if(i*pr[j]>1e6) break;
vis[pr[j]*i]=1;
if(i%pr[j]==0){
phi[i*pr[j]]=phi[i]*pr[j];
break;
}
phi[i*pr[j]]=phi[i]*(pr[j]-1);
}
}
}

浙公网安备 33010602011771号