欧拉函数在数论中,用于求解[1, n]中与n互质数个数的函数。
通式:
φ(x)=x(1-1/p(1))(1-1/p(2))······(1-1/p(i))(1-1/p(i+1))·······(1-1/p(n)); 其中p(1),p(2)…p(n)为x的所有质因数且x是正整数。
例如:
- 12=2*2*3,φ(12)=12*(1-1/2)(1-1/3)=4,因为1、5、7、11与12互质;
- 8=2*2*2,φ(8)=8*(1-1/2)=4,因为1、3、5、7与8互质
- 10=2*5,φ(10)=10*(1-1/2)(1-1/5),因为1、3、7、9与10互质
欧拉函数的性质:
- φ(1)=1(唯一和1互质的数(<=1)就是1本身)
- 每种质因数只有一个。质因数(素因数或质因子)在数论里是指能整除给定正整数的质数
- 若p为质数,如果n=p^k,有φ(n) = p^k-p^(k-1) = (p-1)p^(k-1);如果n=p,有φ(n)=p-1
- 若m, n互质,φ(m*n) = (m-1)*(n-1) =φ(m) * φ(n)
- 特殊的,当n为奇数时,φ(2*n)=φ(n)。
- 欧拉定理:对于任何两个互质的正整数a,n(n>2),有a^φ(n) ≡ 1 mod n
- 小于n的数中,与n互质的数的总和为:φ(n) * n / 2,其中 n>1。
相关例题:
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1286 <找新朋友>
#include<stdio.h>
#include<math.h>
int eular(int n)
{
int i, ret = n;
for(i=2; i<=sqrt(n); i++){
if(n%i==0){
ret = ret/i*(i-1);
while(n%i==0)
n /= i;
}
}
if(n > 1)
ret = ret/n*(n-1);
return ret;
}
int main()
{
int T, n;
scanf("%d", &T);
while(T-- && scanf("%d", &n)){
printf("%d\n", eular(n));
}
return 0;
}
题目链接:http://poj.org/problem?id=1284 <Primitive Roots>
#include<stdio.h>
#define maxn 66666
int euler[maxn+1];
int phi(int n)
{
int res=n;
for(int i=2;i*i<=n;i++)
{
if(n%i==0)
{
res=res-res/i;
while(n%i==0)
n/=i;
}
}
if(n>1)
res=res-res/n;
return res;
}
//筛法范围打表 nlogn
void phi()
{
for(int i=1;i<=maxn;i++)
euler[i]=i;
for(int i=2;i<=maxn;i+=2)
euler[i]/=2;
for(int i=3;i<=maxn;i++)
{
if(euler[i]==i) //未被筛到。是素数,则用此素数来筛
{
for(int j=i;j<=maxn;j+=i)
{
euler[j]=euler[j]/i*(i-1);
}
}
}
return ;
}
int main()
{
int n;
phi();
while(scanf("%d",&n)!=EOF)
{
printf("%d\n",euler[n-1]);
}
}