【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 }