欧拉函数

written by oneman233
2019-08-24

定义

$phi(n)$表示$[1,n-1]$当中有几个数字与$n$互质,规定$phi(1)=1$。

四种求法

单个数的欧拉函数

int eular(int n) {
    int ans=n;
}

for(int i=2;i*i<=n;++i)
if(n%i==0) {
    ans-=ans/i;
    while(n%i==0) n/=i;
}
if(n>1) ans-=ans/n;
return ans

时间复杂度大概在$O(sqrt(n))$附近。

通项公式

如下式:

\[phi(n)=n*(1-1/p1)*...*(1-i/pn)\]

上式中$p1…pn$是$n$的所有质因数。

筛素数时顺便筛欧拉函数

void sieve() {
    int k=0;
    phi[1]=1;
    for(int i=2;i<=maxn;++i) {
        if(!isp[i]) {
            prime[k++]=i;
            phi[i]=i-1;
        }
        for(int j=0;j<k&&i*prime[j]<=maxn;++j) {
            isp[i*prime[j]]=1;
            if(i%prime[j]==0) {
                phi[i*prime[j]]=phi*prime[j];
                break;
            }
            else phi[i*prime[j]]=phi[i]*(prime[j]-1);
        }
    }
}

一个性质

在$[1,n-1]$范围内与$n$互质的所有正整数之和是$n/2*phi[n]$。

筛因子个数

int fac[maxn],low[maxn];
bool isp[maxn];
V<int> p;
void gao3() {
	re(i,2,1e6) {
		if(!isp[i])
			p.pub(i),
			fac[i]=2,
			low[i]=1;
		for(auto j:p) {
			if(j*i>maxn) break;
			isp[j*i]=1;
			if(i%j==0) {
				fac[j*i]=fac[i]/(low[i]+1)*(low[i]+2);
				low[j*i]=low[i]+1;
			}
			else
				fac[j*i]=fac[i]*fac[j],
				low[j*i]=1;
		}
	}
}

更多可参考筛法