标签:
1 #include <stdio.h> 2 #include <math.h> 3 #include <queue> 4 #include <vector> 5 #include <stack> 6 #include <map> 7 #include <string> 8 #include <cstring> 9 #include <algorithm> 10 #include <iostream> 11 #define maxe 500000 12 int a[500010]; 13 int main() 14 { 15 int T,i,j; 16 scanf("%d",&T); 17 memset(a,0,sizeof(a)); 18 for(i=1;i<=maxe;i++) 19 { 20 for(j=2;i*j<=maxe;j++) 21 { 22 a[i*j]=a[i*j]+i; 23 } 24 } 25 int n; 26 while(T--) 27 { 28 scanf("%d",&n); 29 printf("%d\n",a[n]); 30 } 31 return 0; 32 33 }
下面是来自别人的博客:
1.素数打表,这个就不说了,基本功。
2.接下来就是这个问题的关键:素分解。不会的可以移步这篇文章:http://wenku.baidu.com/view/e55ca209ba1aa8114431d98a.html
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<string> 5 #include<cmath> 6 #include<algorithm> 7 using namespace std; 8 9 #define CLR(arr, what) memset(arr, what, sizeof(arr)) 10 const int N = 500002; 11 12 int prim[N]; 13 bool visit[N]; 14 15 void fast_prim() //素数打表 16 { 17 memset(visit, true, sizeof(visit)); 18 int limit = (int)sqrt(N * 1.0); 19 for(int i = 2; i < limit; ++i) 20 if(visit[i]) 21 for(int j = i * i; j < N; j += i) 22 visit[j] = false; 23 for(int i = 2, j = 0; i < 10000; ++i) 24 if(visit[i]) 25 prim[j++] = i; 26 } 27 28 int prim_reduce(int n) //整数素分解 29 { 30 int limit, num, sum, total = 1, temp = n; 31 limit = sqrt(N * 1.0); 32 for(int i = 0; prim[i] * prim[i] <= n; ++i) 33 { 34 num = sum = 1; 35 if(n == 1) 36 break; 37 while(n % prim[i] == 0) 38 { 39 num *= prim[i]; 40 n /= prim[i]; 41 sum += num; 42 } 43 total *= sum; 44 } 45 if(n != 1) 46 total *= (n + 1); 47 return total - temp; 48 } 49 50 int main() 51 { 52 fast_prim(); 53 int ncase; 54 int num; 55 scanf("%d", &ncase); 56 while(ncase--) 57 { 58 scanf("%d", &num); 59 if(num == 1) 60 { 61 printf("0\n"); 62 continue; 63 } 64 else if(visit[num]) 65 { 66 printf("1\n"); 67 continue; 68 } 69 else 70 printf("%d\n", prim_reduce(num)); 71 } 72 return 0; 73 }
在于打表的过程不同,这种方法是解决这种问题的通法
标签:
原文地址:http://www.cnblogs.com/wangmengmeng/p/4701911.html