通式: $\phi(x)=x(1-\frac{1}{p_1})(1-\frac{1}{p_2})(1-\frac{1}{p_3}) \cdots (1-\frac{1}{p_n})$
若n是質數p的k次冪:$\phi(n)=p^k-p^{k-1}=(p-1)p^{k-1}$,因為除了p的倍數外,其他數都跟n互質。
設n為正整數,以$\phi(n)$表示不超過n且與n互素的正整數的個數,稱為n的尤拉函式值,這裡函式φ:N→N,n→φ(n)稱為尤拉函式。
尤拉函式是積性函式——若m,n互質, $\phi(mn)=\phi(m)\phi(n)$
特殊性質:當n為奇數時, $\phi(2n)=\phi(n)$, 證明與上述類似。
若n為質數則 $\phi(n)=n-1$
zky學長上課時留的思考題,關於$n = \sum_{d|n} \phi(d)$的證明:
①當$n$為質數時,顯而易見$n= \sum_{d|n} \phi(d)= \phi(1) + \phi(n) = n$
②當$n=p^a$時
\[ \begin{aligned} n & = \sum_{d|n} \phi(d) \\ & = \sum_{i=0}^a \phi(p^i) \\ & = \phi(1) + \phi(p^1) + \phi(p^2) + \cdots + \phi(p^a) \\ & = 1 + p^1-p^0+p^2-p^1+ \cdots +p^a-p^{a-1} \\ = p^a = n \end{aligned} \]
③當$n$為其他情況時,將$n$分解質因數得$n=p_{1}^{a_{1}}p_{2}^{a_{2}} \cdots p_{k}^{a_{k}}$,對於每個$p_{i}^{a_{i}}$是互質的,那麼由積性函式的性質($n$和$m$互質,則$\phi(nm)=\phi(n)\phi(m)$)和②中的證明可以得出結論,是不是很簡單啊
單個尤拉函式求法:
int euler_phi(int n){
int m=(int)sqrt(n+0.5);
int ans=n;
for(int i=2;i<=m;++i)
if (n%i==0){
ans=ans/i*(i-1);
while (n%i==0)
n/=i;
}
if (n>1) ans=ans/n*(n-1);
}
尤拉篩,參考白書上的:
int phi[maxn];
void phi_table(int n){
for(int i=2;i<=n;++i)
phi[i]=0;
phi[1]=1;
for(int i=2;i<=n;++i)
if (!phi[i])
for(int j=i;j<=n;j+=i){
if (!phi[j])
phi[j]=j;
phi[j]=phi[j]/i*(i-1);
}
}
POJ 2478 O(n)內篩法:
#include<cstdio>
using namespace std;
const int N=1000003;
int num=0,prime[N],phi[N];
bool notp[N];
inline void shai(){
phi[1]=1;
for(int i=2;i<N;++i){
if (!notp[i]){
prime[++num]=i;
phi[i]=i-1;
}
for(int j=1;j<=num&&i*prime[j]<N;++j){
notp[i*prime[j]]=1;
if (i%prime[j]==0){
phi[i*prime[j]]=phi[i]*prime[j];
break;
}else
phi[i*prime[j]]=phi[i]*phi[prime[j]];
}
}
}
int main(){
shai();
int x;
long long ans;
scanf("%d\n",&x);
while (x){
ans=0;
for(int i=2;i<=x;++i)
ans+=phi[i];
printf("%I64d\n",ans);
scanf("%d\n",&x);
}
return 0;
}
這樣就可以啦