欧拉函数

欧拉函数

定义

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

计算公式

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

积性函数

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

常用性质

  • 对于素数 p p p φ ( p ) = p − 1 , φ ( p k ) = p k − p k − 1 φ(p)=p-1,φ(p^k)=p^k-p^{k-1} φ(p)=p1φ(pk)=pkpk1
  • n > 2 ​ n>2​ n>2 时, φ ( n ) ​ φ(n)​ φ(n) 是偶数,即当 g c d ( m , n ) = 1 ​ gcd(m,n)=1​ gcd(m,n)=1 时,有 g c d ( 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) ,即 n n n 的因数(包括1和本身)的欧拉函数之和等于 n n n

实现代码

  • 根据公式计算 φ ( n ) φ(n) φ(n) 直接枚举 n n n 的所有素因子,复杂度和因式分解相同 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 × l n l n ( n ) ) O(n×lnln(n)) O(n×lnln(n))
int phi[maxn];

void init(){
	for(int i=1;i
  • 欧拉筛,每个数被最小的因子筛掉的同时,再进行判断。 i i i 表示当前做到的这个数, p r i m e [ j ] prime[j] prime[j] 表示当前做到的质数,那要被筛掉的合数就是 i ∗ p r i m e [ j ] i*prime[j] iprime[j],若 i   %   p r i m e [ j ] ≠ 0 i \ \% \ prime[j]\neq0 i % prime[j]̸=0,也就是 g c d ( i , p r i m e [ j ] ) = 1 gcd(i,prime[j])=1 gcd(i,prime[j])=1 互质时,则根据欧拉函数的积性函数的性质, φ ( i ∗ p r i m e [ j ] ) = φ ( i ) × φ ( p r i m e [ j ] ) φ(i * prime[j])=φ(i) ×φ(prime[j]) φ(iprime[j])=φ(i)×φ(prime[j])。若 i   %   p r i m e [ j ] = 0 i \ \% \ prime[j]=0 i % prime[j]=0,也就是这个合数的所有质因子都在i里出现过,那么根据公式,
    φ ( i × p r i m e [ j ] ) = i × p r i m e [ j ] × ∏ k = 1 n ( 1 − 1 p k ) = p r i m e [ 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

你可能感兴趣的:(数学-----------数论)