欧拉函数
定义
欧拉函数是小于x的整数中与x互质的数的个数,一般用 表示。特殊的,
计算公式
设 的所有素因子分别为 ,则
用容斥原理证明即可
积性函数
欧拉函数是积性函数,当 时,
常用性质
- 对于素数 ,
- 时, 是偶数,即当 时,有 ,和 互素的数总是成对出现
- 根据上一条可得,小于 的数中,与 互质的数的总和为
- ,即 的因数(包括1和本身)的欧拉函数之和等于
实现代码
- 根据公式计算 直接枚举 的所有素因子,复杂度和因式分解相同
int phi(int n){ int m=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); return ans; }
- 埃氏筛,找到一个素数,更新它和它的倍数,复杂度
int phi[maxn]; void init(){ for(int i=1;i<maxn;++i) phi[i]=i; for(int i=2;i<maxn;++i){ if(phi[i]==i){//代表i是素数 for(int j=i;j<maxn;j+=i){ phi[j]=phi[j]/i*(i-1); } } } }
-
欧拉筛,每个数被最小的因子筛掉的同时,再进行判断。 表示当前做到的这个数, 表示当前做到的质数,那要被筛掉的合数就是 ,若 ,也就是 互质时,则根据欧拉函数的积性函数的性质,。若 ,也就是这个合数的所有质因子都在i里出现过,那么根据公式,
int prime[maxn],tot; int vis[maxn],phi[maxn]; void init(){ phi[1]=1; for(int i=2;i<maxn;++i){ if(!vis[i]){ prime[tot++]=i; phi[i]=i-1; } for(int j=0;j<tot && 1LL*i*prime[j]<maxn;++j){ vis[i*prime[j]]=1; if(i%prime[j]) phi[i*prime[j]]=phi[i]*phi[prime[j]]; else{ phi[i*prime[j]]=phi[i]*prime[j]; break; } } } }
文章来源: https://blog.csdn.net/xiao_k666/article/details/89736285