【欧拉函数表】POJ2478-Farey Sequence

【题目大意】

求∑φ(i)(1<=i<=N)。

【思路】

欧拉函数具有如下的重要推论:

当b是素数时

性质①若b|a,有φ(ab)=φ(a)*b;

性质②若b不|a,有φ(ab)=φ(a)*(b-1)。

由此可以得出递推求欧拉函数表的方法:

对于当前φ(i),若未被修改过,这说明它是素数,加入素数表。

对于每个i,枚举小于它的所有素数j。利用性质1和性质2求出φ(ij)

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 using namespace std;
 7 const int MAXN=1000000+50;
 8 typedef long long ll;
 9 int n,maxn;
10 int phi[MAXN],p[MAXN],input[MAXN];
11 ll s[MAXN];
12 int t=0;
13 
14 void eular_table()
15 {
16     memset(phi,0,sizeof(phi));
17     memset(p,0,sizeof(p));
18     p[0]=1;p[1]=2;phi[2]=1;
19     for (int i=2;i<=maxn;i++)
20     {
21         if (phi[i]==0)
22         {
23             p[++p[0]]=i;
24             phi[i]=i-1;
25         }
26         for (int j=1;j<=p[0];j++)
27         {
28             if (i*p[j]<=maxn) phi[i*p[j]]=(i%p[j]==0)? phi[i]*p[j] : phi[i]*(p[j]-1);
29             //注意一定要保证i*p[j]没有超出数组上界,否则RE
30                 else break;
31         }
32     }
33 }
34 
35 void printans()
36 {
37     s[0]=0;
38     for (int i=1;i<=maxn;i++) 
39         s[i]=s[i-1]+phi[i];
40     for (int i=0;i<t;i++)
41         printf("%lld
",s[input[i]]);
42 }
43 
44 int main()
45 {
46     while (~scanf("%d",&n) && n!=0)
47     {
48         input[t++]=n;
49         maxn=max(maxn,n);
50     }
51     eular_table();
52     printans();
53     return 0;
54 }
原文地址:https://www.cnblogs.com/iiyiyi/p/5544401.html