poj2407 欧拉定理解题报告报告
http://poj.org/problem?id=2407
Description
Given n, a positive integer, how many positive integers less than n are relatively prime to n? Two integers a and b are relatively prime if there are no integers x > 1, y > 0, z > 0 such that a = xy and b = xz.
Input
就是求小于n且与n互质的数的个数
这题使用到欧拉函数:
对正整数n,欧拉函数是少于或等于n的数中与n互质的数的数目。此函数以其首名研究者欧拉命名,它又称为Euler's totient function、φ函数、欧拉商数等。 例如φ(8)=4,因为1,3,5,7均和8互质。
φ函数的值
通式:φ(x)=x(1-1/p1)(1-1/p2)(1-1/p3)(1-1/p4)…..(1-1/pn),其中p1, p2……pn为x的所有质因数,x是不为0的整数。φ(1)=1(唯一和1互质的数就是1本身)。
若n是质数p的k次幂,φ(n)=p^k-p^(k-1)=(p-1)p^(k-1),因为除了p的倍数外,其他数都跟n互质。
欧拉函数是积性函数——若m,n互质,φ(mn)=φ(m)φ(n)。
特殊性质:当n为奇数时,φ(2n)=φ(n), 证明于上述类似。
证明略
举例:
ψ(10)=10×(1-1/2)×(1-1/5)=4;
ψ(30)=30×(1-1/2)×(1-1/3)×(1-1/5)=8;
ψ(49)=49×(1-1/7)=42。
我的代码:
#include<cstdio>
#include<iostream>
using namespace std;
#include<cmath>
int num[100000];
int f_Euler(int s,int a)//返回欧拉数的个数,s是数组num里数据的个数,a是原来输入数据,即n
{
double ans=a;
int i;
for(i=1;i<=s;i++)
{
ans*=(1-1.0/num[i]);
}
return (int)(ans+0.1);
}
int main()
{
num[0]=1;//无用
int a,b,s,i,max,t;
while(scanf("%d",&a)&& a)
{
t=a;
s=0;
//以下为分解质因数
max=sqrt(double(a))+1;
if(a%2==0){
while(a%2==0){
a=a/2;
}
num[++s]=2;
}
for(int i=3;i<=max;i+=2)
{
if(a%i==0){
while(a%i==0){
a=a/i;
}
num[++s]=i;
}
}
if(a!=1)num[++s]=a;//分解最后剩下的数(可能大于sqrt(n))
printf("%d\n",f_Euler(s,t));
memset(num,0,sizeof(int)*s);
}
return 0;
}
poj上一个优化的代码:
while(scanf("%d",&n),n != 0){
if(n == 1){
printf("0\n"); continue;
}
ans = n;
for(int i = 2;i*i <= n;++i){
if( n % i == 0 ){
ans = ans - ans/i;//见注释
while(n%i == 0){
n /= i;
}
}
}
// n is prime itself
if(n != 1) ans = ans - ans / n;
printf("%d\n",ans);
}
注释:
ans = ans - ans/i其实就是
欧拉定理ans*=(1-1.0/num[i]);的简化版,深入理解欧拉函数后就知道是:ans/i是小于等于ans被i整除的数的个数..
附:
2-100欧拉函数表(供测试用)
n φ(n)
2 1
3 2
4 2
5 4
6 2
7 6
8 4
9 6
10 4
11 10
12 4
13 12
14 6
15 8
16 8
17 16
18 6
19 18
20 8
21 12
22 10
23 22
24 8
25 20
26 12
27 18
28 12
29 28
30 8
31 30
32 16
33 20
34 16
35 24
36 12
37 36
38 18
39 24
40 16
41 40
42 12
43 42
44 20
45 24
46 22
47 46
48 16
49 42
50 20
51 32
52 24
53 52
54 18
55 40
56 24
57 36
58 28
59 58
60 16
61 60
62 30
63 36
64 32
65 48
66 20
67 66
68 32
69 44
70 24
71 70
72 24
73 72
74 36
75 40
76 36
77 60
78 24
79 78
80 32
81 54
82 40
83 82
84 24
85 64
86 42
87 56
88 40
89 88
90 24
91 72
92 44
93 60
94 46
95 72
96 32
97 96
98 42
99 60
100 40