Description
Input
Output
Sample Input
2 3 4 5 0
Sample Output
1 3 5 9
欧拉函数的应用
很简单的一道题,但是直接使用欧拉函数会TLE
1 #include<stdio.h> 2 #include<math.h> 3 #define N 1000010 4 5 //欧拉函数 <模板> 6 int euler_phi(int n) 7 { 8 int m = (int)sqrt(n+0.5); 9 int ans = n; 10 for(int i = 2; i <= m; i++) 11 if(n % i == 0){//找素因子 12 ans = ans/i*(i-1); 13 while(n % i == 0) 14 n /= i;//除尽 15 } 16 if(n>1) 17 ans = ans/n*(n-1); 18 return ans; 19 } 20 21 int main() 22 { 23 int n; 24 while(scanf("%d", &n) && n != 0){ 25 int sum = 0; 26 for (int i = 2; i <= n; i ++) 27 sum += euler_phi(i); 28 printf("%d\n", sum); 29 } 30 return 0; 31 }
于是,我们需要进行一些改进,欧拉函数可以写成递归形式,类似于记忆化搜索,我们不需要每次都重复计算,也就是所谓的欧拉函数打表
其中需要注意的一点就是,当 n 的值比较大的时候, sum 会超出 int 的范围(当输入 n 的值为100000时就会发现输出为负值),所以要改成long long 类型或者 _int64 类型
1 #include<math.h> 2 #include<stdio.h> 3 #include<string.h> 4 #define maxn 1000010 5 6 //欧拉函数打表 <模板> 7 int phi[maxn]; 8 void phi_table(int n) 9 { 10 for(int i = 2; i <= n; i++) 11 phi[i] = 0; 12 phi[1] = 1; 13 for(int i = 2; i <= n; i++) 14 if(!phi[i]) 15 for(int j = i; j <= n; j += i){ 16 if(!phi[j]) 17 phi[j] = j; 18 phi[j] = phi[j]/i*(i-1); 19 } 20 } 21 22 23 int main() 24 { 25 memset(phi, 0, sizeof(phi)); 26 phi_table(maxn); 27 int n; 28 while(scanf("%d", &n) && n != 0){ 29 long long sum = 0; 30 for(int i = 2; i <= n; i++) 31 sum += phi[i]; 32 printf("%lld\n", sum); 33 } 34 return 0; 35 }