【poj 2407】Relatives(数论--欧拉函数 模版题)

题意就是求10^9以内的正整数的欧拉函数(Φ(n)表示<=n的与n互质的正整数个数)。

解法:用欧拉筛和欧拉函数的一些性质:
    1.若p是质数,Φ(p)=p-1;
    2.欧拉函数是积性函数,即若a,b互质,则Φ(ab)=Φ(a)*Φ(b);
    3.若a,b不互质,则Φ(ab)=Φ(a)*b。

若 n≤10^6,可以通过欧拉筛用数组预处理得出;若不是,再分解质因数,利用Φ(n)=n*(1-1/p1)*(1-1/p2)*...*(1-1/pk) {除去各质因数的 n 以内的倍数}求出。

P.S. n 不是10^6以内分解质因数并求解时要注意啊,我WA了7次! %>_<%

P.P.S. 这题数据弱,不用欧拉筛更快......不写mn_prim,而用标记数组也是可以的。

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<iostream>
 6 using namespace std;
 7 #define N (int)1e9
 8 #define M (int)1e6
 9 typedef long long LL;
10 
11 int phi[M+10],prim[M+10],mn_prim[M+10];
12 int pr=0;
13 
14 void get_prime()
15 {
16     memset(mn_prim,0,sizeof(mn_prim));
17     for (int i=2;i<=M;i++)
18     {
19       if (!mn_prim[i])
20       {
21         prim[++pr]=i;
22         phi[i]=i-1;
23       }
24       for (int j=1;j<=pr,i*prim[j]<=M;j++)
25       {
26         mn_prim[i*prim[j]]=prim[j];
27         if (i%prim[j]!=0)
28           phi[i*prim[j]]=phi[i]*phi[prim[j]];
29         else
30         {
31           phi[i*prim[j]]=phi[i]*prim[j];
32           break;
33         }
34       }
35     }
36 }
37 int main()
38 {
39     get_prime();
40     int n;
41     while (1)
42     {
43       scanf("%d",&n);
44       if (!n) break;
45       if (n<=M-10) printf("%d\n",phi[n]);
46       else
47       {
48         int cnt=n,t=n;
49         for (int i=2;i<=t;i++)//t
50         {
51           if (t%i==0)
52           {
53             cnt-=cnt/i;//  cnt*(1-1/i);
54             while (t%i==0) t/=i;
55           }
56           if (t==1) break;
57         }
58         printf("%d\n",cnt);
59       }
60     }
61     return 0;
62 }

 

posted @ 2016-11-15 19:37  konjac蒟蒻  阅读(254)  评论(0编辑  收藏  举报