欧拉函数

欧拉函数φ(x)定义为小于x且与x互质的整数个数,对于素数p,φ(p)=p-1。φ函数具有积性性质,当gcd(n,m)=1时,φ(n×m)=φ(n)×φ(m)。文章介绍了欧拉函数的计算公式,常用性质,并提供了两种实现代码:直接枚举素因子和使用埃氏筛、欧拉筛的方法。" 82499957,5855363,水经注与bigemap地图下载工具对比分析,"['GIS工具', '地图数据', '软件比较', '地理信息处理', '数据下载']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

欧拉函数

定义

欧拉函数是小于x的整数中与x互质的数的个数,一般用 φ(x)​φ(x)​φ(x) 表示。特殊的,φ(1)=1​φ(1)=1​φ(1)=1

计算公式

xxx 的所有素因子分别为 p1,p2,...pnp_1,p_2,...p_np1,p2,...pn,则
φ(x)=x×∏1n(1−1pi) φ(x)=x×\prod^{n}_{1}(1-\frac{1}{p_i}) φ(x)=x×1n(1pi1)
用容斥原理证明即可

积性函数

欧拉函数是积性函数,当 gcd(n,m)=1​gcd(n,m)=1​gcd(n,m)=1 时,φ(n×m)=φ(n)×φ(m)​φ(n×m)=φ(n)×φ(m)​φ(n×m)=φ(n)×φ(m)

常用性质

  • 对于素数 pppφ(p)=p−1,φ(pk)=pk−pk−1φ(p)=p-1,φ(p^k)=p^k-p^{k-1}φ(p)=p1φ(pk)=pkpk1
  • n>2​n>2​n>2 时,φ(n)​φ(n)​φ(n) 是偶数,即当 gcd(m,n)=1​gcd(m,n)=1​gcd(m,n)=1 时,有 gcd(n−m,m)=1​gcd(n-m,m)=1​gcd(nm,m)=1,和 n​n​n 互素的数总是成对出现
  • 根据上一条可得,小于 n​n​n 的数中,与 n​n​n 互质的数的总和为 φ(n)×n/2(n>1)​φ(n)×n / 2 (n>1)​φ(n)×n/2(n>1)
  • n=∑d∣nφ(d)n=\sum_{d|n}φ(d)n=dnφ(d) ,即 nnn 的因数(包括1和本身)的欧拉函数之和等于 nnn

实现代码

  • 根据公式计算 φ(n)φ(n)φ(n) 直接枚举 nnn 的所有素因子,复杂度和因式分解相同 O(n)O(\sqrt{n})O(n)
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;
}
  • 埃氏筛,找到一个素数,更新它和它的倍数,复杂度 O(n×lnln(n))O(n×lnln(n))O(n×lnln(n))
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);
			}
		}
	}
}
  • 欧拉筛,每个数被最小的因子筛掉的同时,再进行判断。iii 表示当前做到的这个数,prime[j]prime[j]prime[j] 表示当前做到的质数,那要被筛掉的合数就是 i∗prime[j]i*prime[j]iprime[j],若 i % prime[j]≠0i \ \% \ prime[j]\neq0i % prime[j]̸=0,也就是 gcd(i,prime[j])=1gcd(i,prime[j])=1gcd(i,prime[j])=1 互质时,则根据欧拉函数的积性函数的性质,φ(i∗prime[j])=φ(i)×φ(prime[j])φ(i * prime[j])=φ(i) ×φ(prime[j])φ(iprime[j])=φ(i)×φ(prime[j])。若 i % prime[j]=0i \ \% \ prime[j]=0i % prime[j]=0,也就是这个合数的所有质因子都在i里出现过,那么根据公式,
    φ(i×prime[j])=i×prime[j]×∏k=1n(1−1pk)=prime[j]×φ(i) φ(i×prime[j])=i×prime[j]×\prod_{k=1}^{n}(1-\frac{1}{p_k})=prime[j]×φ(i) φ(i×prime[j])=i×prime[j]×k=1n(1pk1)=prime[j]×φ(i)
    即可线性筛选 O(n)O(n)O(n)
    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;
    			}
    		}
    	}
    }
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值