欧拉函数用来计算比n小且和n互质的正整数的个数,记做:φ(n),其中φ(1)被定义为1,但是并没有任何实质的意义。
(1)当n为质数时,显然φ(n)=n-1;
(2)当n为质数P^k时,φ(n)=p^k - p^(k-1)
证明:已知少于小于p^k的正整数个数为p^k-1个,其中 和p^k不互质的正整数有{p×1,p×2,...,p×(p^(k-1)-1)}共计p^(k-1)-1个 所以Φ(n) = p^k -1 - (p^(k-1)-1) = p^k - p^(k-1 )
(3)当n=p×q,p、q均为质数时,φ(n)=φ(p)*φ(q)
证明:定义小于n且和n互质的数构成的集合为Zn,称呼这个集合为n的完全余数集合。
考虑n的完全余数集Zn = { 1,2,....,pq -1}
而不和n互质的集合由下面三个集合的并构成:
1) 能够被p整除的集合{p,2p,3p,....,(q-1)p} 共计q-1个
2) 能够被q整除的集合{q,2q,3q,....,(p-1)q} 共计p-1个
3) {0}
Zn中元素个数 = pq - (p-1 + q- 1 + 1) = (p-1)(q-1)
(4)设n=p1^a1*p2^a2...pk^ak
可以得出φ(n)=n(1-1/p1)(1-1/p2)...(1-1/pk)
(5)实际的实现:
我们用根号N的时间,将n分解,根据第三点,分别算出每个质因子的欧拉函数,再相乘即可。
复杂度O(根号N)
Status | In/Out | TIME Limit | MEMORY Limit | Submit Times | Solved Users | JUDGE TYPE |
---|---|---|---|---|---|---|
stdin/stdout | 3s | 8192K | 416 | 178 | Standard |
There are several test cases. For each test case, standard input contains a line with n <= 1,000,000,000. A line containing 0 follows the last case.
For each test case there should be single line of output answering the question posed above.
7 12 0
6 4
#include<stdio.h>
int main()
{
int n,k;
while(scanf("%d",&n)&&n)
{
int b=n;k=2;
int res=n;
while(k<=b)
{
if(b%k==0)
{
res-=res/k;
b/=k;
}
while(b%k==0) b/=k;
if(b==1) break;
k++;
}
if(b==n)
{
printf("%d/n",n-1);
continue;
} //if(b>1&&b<n) res-=res/k;
printf("%d/n",res);
}
return 0;
}
#include<stdio.h>
#include<math.h>
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int n,res,m,i;
while((scanf("%d",&n),n)!=0)
{
if(n==1) printf("1/n");
else
{
res=n;
m=n;
i=2;
while(res>1&&i<=n)
{
if(res%i==0) m=m/i*(i-1);
while(res%i==0)
res=res/i;
i++;
}
if(res==n) printf("%d/n",n-1);
else printf("%d/n",m);
}
}
return 0;
}