【模板】【数学】欧拉函数
原文链接:https://blog.csdn.net/on_the_road344/article/details/45178243
对于正整数n,φ(n)是小于或等于n的正整数中,与n互质的数的数目;
欧拉函数就是用来求这个的。
公式: φ(x)=x(1-1/p(1))(1-1/p(2))(1-1/p(3))(1-1/p(4))…..(1-1/p(n)) 其中p(1),p(2)…p(n)为x 的所有质因数;x是正整数; φ(1)=1(唯一和1互质的数,且小于等于1)。注意:每种质因数只有一个。
有两种方法求,一种直接求,一种线性求。
1 //直接求解欧拉函数 2 int euler(int n){ //返回euler(n) 3 int res=n,a=n; 4 for(int i=2;i*i<=a;i++){ 5 if(a%i==0){ 6 res=res/i*(i-1);//先进行除法是为了防止中间数据的溢出 7 while(a%i==0) a/=i; 8 } 9 } 10 if(a>1) res=res/a*(a-1); 11 return res; 12 } 13 14 //筛选法打欧拉函数表 15 #define Max 1000001 16 int euler[Max]; 17 void Init(){ 18 euler[1]=1; 19 for(int i=2;i<Max;i++) 20 euler[i]=i; 21 for(int i=2;i<Max;i++) 22 if(euler[i]==i) 23 for(int j=i;j<Max;j+=i) 24 euler[j]=euler[j]/i*(i-1);//先进行除法是为了防止中间数据的溢出 25 }
线性筛求欧拉函数
1 void getphi() 2 { 3 int i,j; 4 phi[1]=1; 5 for(i=2;i<=N;i++)//相当于分解质因式的逆过程 6 { 7 if(!mark[i]) 8 { 9 prime[++tot]=i;//筛素数的时候首先会判断i是否是素数。 10 phi[i]=i-1;//当 i 是素数时 phi[i]=i-1 11 } 12 for(j=1;j<=tot;j++) 13 { 14 if(i*prime[j]>N) break; 15 mark[i*prime[j]]=1;//确定i*prime[j]不是素数 16 if(i%prime[j]==0)//接着我们会看prime[j]是否是i的约数 17 { 18 phi[i*prime[j]]=phi[i]*prime[j];break; 19 } 20 else phi[i*prime[j]]=phi[i]*(prime[j]-1);//其实这里prime[j]-1就是phi[prime[j]],利用了欧拉函数的积性 21 } 22 } 23 }

浙公网安备 33010602011771号