当前位置: 代码迷 >> 综合 >> ACM_欧拉函数(eular) 及其引申性质
  详细解决方案

ACM_欧拉函数(eular) 及其引申性质

热度:70   发布时间:2023-12-06 03:24:07.0

欧拉函数(eular)是一个在数论中使用比较多的算法。欧拉函数表示的是比一个数n小的正整数数中和n互质的数的个数,用φ(n)来表示。定义很简单关键是计算的问题。我们先看一下欧拉函数的性质:

1.首先,如果n是一个质数,那么比n小的数都和它互质,也就是说φ(n) = n-1。

2.如果一个数是一个质数p的幂,即n = p^k,则φ(n) = p^k-p^(k-1) = (p-1)*p^(k-1),证明:

n只与是p的倍数的数互质,n = p^k = p*p^(k-1),也就是说在1~n的范围内有k-1个数是p的倍数,所以φ(n) = p^k-p^(k-1) = (p-1)*p^(k-1)。

3.当n,m互质的时候,φ(n*m) = φ(n)*φ(m)。

4.一个数可以分成几个质因子的幂的乘积,运用性质2,3,我们可以推出一个公式:

φ(n)=(p1-1)(p2-1)...(pi-1)*(p1^(a1-1))(p2^(a2-1))...(pi^(ai-1))

= k*(p1-1)(p2-1)...(pi-1)/(p1*p2*...*pi)

= k*(1-1/p1)*(1-1/p2)...(1-1/pk)

5.同样,根据性质2,3,我们可以推出一个递推公式:

若( n%a ==0&&(n/a)%a ==0)则有:φ(n)=φ(n/a)*a;
若( n%a ==0&&(n/a)%a !=0)则有:φ(n)= φ(n/a)*(a-1);

在ACM编程中,如果是求单个的欧拉函数的时候,我们选择用性质4,5都行,但是如果需要预处理的话我们一般选择用性质5,因为性质5强调的是相互之间的关系,可以运用递推叠上去

求单个数的欧拉函数模板:

LL eular(LL n)//性质5 
{LL 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;
}LL eular(LL n)//性质4 
{LL p = 1;for(int i=2; i*i<=n; i++)if(n % i == 0){n /= i;p *= i-1;while(n%i==0){n /= i;p *= i;}}if(n>1) p *= n-1;return p;
}

预处理模板:

void eular()
{int cnt = 0;for(int i=2; i<maxn; i++){if(isprime[i] == 0){prime[cnt++] = i;phi[i] = i-1;}for(int j=0; j<cnt && i*prime[j] < maxn; j++){isprime[i*prime[j]] = 1;if(i % prime[j] == 0) phi[i*prime[j]] = phi[i]*prime[j];else phi[i*prime[j]] = phi[i]*(prime[j]-1);}}
}

讲完了这些基本的性质,我们来讲eular函数的一些引申的性质,首先小编先给出性质再给予证明:

在1..N中与N互质的数的和S = N*eular(N)/2;

在证明这条性质之前,我们先证明另一条数学性质:

如果gcd(n,m) = 1,则一定存在gcd(n,n-m) = 1;

这个性质很好证明,我们只需要假设一下反证即可,假设gcd(n,m) = 1,而gcd(n,n-m) = x(x!=1),那么说明x是n的因数,也同时是n-m的因子,如果要同时满足这两条,那么一定存在x也是m的因子,所以gcd(n,m) != 1,所以如果gcd(n,m) = 1,则一定存在gcd(n,n-m) = 1;

那么有了这个性质之后,我们就可以证明欧拉函数的这个引申性质了,如果m与n互质,那么一定存在n-m也和n互质,而这两个数的和就是n,所以我们就得到了在1..N中与N互质的数的和S = N*eular(N)/2。