【学习笔记】欧拉函数

欧拉函数

欧拉函数 $\varphi(x) $ 等于在 \([1,x]\) 区间内和 \(x\) 互质的数的个数。

\(\varphi(x)\) 有个便于计算的公式,可以表示为:

\[\varphi(x)=x \times \prod_{p|x}(1-\frac{1}{p}) \]

其中 \(p\) 为素数。

ll phi(ll x){
	ll f=x;
	for(ll p=2;p*p<=x;p++){
		if(x%p) continue;
		f=f/p*(p-1);
		while(!(x%p)) x/=p;
	}
	if(x>1) f=f/x*(x-1);
	return f;
}

注:若 \(x\) 很大,要先除再乘,不然可能会爆 long long。

并且 \(\varphi(x)\) 是个积性函数,即若 \(p,q\) 互质,则有 \(\varphi(pq)=\varphi(p) \times \varphi(q)\)。另外还有两个重要的特点:

  1. \(n \% k == 0\) 则有 \(\varphi(nk)=\varphi(n) \times k\)

  2. \(n \% k != 0\) 则有 \(\varphi(nk)=\varphi(n) \times (k-1)\)

通过这些,可以 \(O(n)\) 筛素数的同时处理出每个 \(\varphi(i)\) 对应的值。

int phi[N],pr[N],cnt;
bool vis[N];
void getphi(){
	phi[1]=1;
	for(int i=2;i<=1e6;i++){
		if(!vis[i]){
			pr[++cnt]=i;
			phi[i]=i-1;
		}
		for(int j=1;j<=cnt;j++){
			if(i*pr[j]>1e6) break;
			vis[pr[j]*i]=1;
			if(i%pr[j]==0){
				phi[i*pr[j]]=phi[i]*pr[j];
				break;
			}
			phi[i*pr[j]]=phi[i]*(pr[j]-1);
		}
	}
}
posted @ 2025-07-17 19:16  tyh_27  阅读(5)  评论(0)    收藏  举报