我们规定φ(p)表示1~p-1中与p互质的数的个数,规定φ(1)=1。
有以下性质:
1.当p为素数是φ(p)=p-1
2.设m>1,(a,m)=1,则:
aφ(m)≡1(mod m). (欧拉定理)
3.设p为素数,(a,p)=1,则:
ap-1≡1(mod p).(费马小定理)
4.若i mod p==0(即p | i),那么φ(i*p)=φ(i)*p
5.若i mod p!=0,那么φ(i*p)=φ(i)*(p-1)
//限于篇幅,均不证明
那么我们该如何计算φ呢?暴力?显然是不行的。
1.若(m1,m2)=1,则φ(m1*m2)=φ(m1)*φ(m2)
2.由上面的定理可以推得φ的计算公式:
设n>1且其标准分解式为n=p1a1*p2a2*p3a3...pkak,则:
φ(n)=n*(1-1/p1)(1-1/p2)(1-1/p3)...(1-1/pk).
我们可能需要写程序来计算φ,我们考虑在线筛的同时求解。
求解方法利用了性质1,4,5.
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
bool b[100010];
int n,prime[100010],total,phi[100010];
int main()
{
scanf("%d",&n);
b[0]=b[1]=1;
phi[1]=1;
for(int i=2;i<=n;i++)
{
if(!b[i])
{
prime[++total]=i;
phi[i]=i-1;//性质1
}
for(int j=1;j<=total;j++)
{
if(i*prime[j]>n)break;
b[i*prime[j]]=1;
if(i%prime[j]==0)
{
phi[i*prime[j]]=phi[i]*prime[j];//性质4
break;
}
else
phi[i*prime[j]]=phi[i]*(prime[j]-1);//性质5
}
}
for(int i=1;i<=n;i++)printf("%d ",phi[i]);
}
原文:https://www.cnblogs.com/zzh666/p/8830928.html