Problem Description
七夕节那天,月老来到数字王国,他在城门上贴了一张告示,并且和数字王国的人们说:"你们想知道你们的另一半是谁吗?那就按照告示上的方法去找吧!"
人们纷纷来到告示前,都想知道谁才是自己的另一半.告示如下:
![](http://acm.hdu.edu.cn/data/images/C8-1006-1.jpg)
数字N的因子就是所有比N小又能被N整除的所有正整数,如12的因子有1,2,3,4,6.
你想知道你的另一半吗?
人们纷纷来到告示前,都想知道谁才是自己的另一半.告示如下:
![](http://acm.hdu.edu.cn/data/images/C8-1006-1.jpg)
数字N的因子就是所有比N小又能被N整除的所有正整数,如12的因子有1,2,3,4,6.
你想知道你的另一半吗?
Input
输入数据的第一行是一个数字T(1<=T<=500000),它表明测试数据的组数.然后是T组测试数据,每组测试数据只有一个数字N(1<=N<=500000).
Output
对于每组测试数据,请输出一个代表输入数据N的另一半的编号.
Sample Input
3
2
10
20
Sample Output
1
8
22
Author
Ignatius.L
Source
Recommend
//此处思想类似于筛法求素数的思想
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 ",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 "); 62 continue; 63 } 64 else if(visit[num]) 65 { 66 printf("1 "); 67 continue; 68 } 69 else 70 printf("%d ", prim_reduce(num)); 71 } 72 return 0; 73 }
在于打表的过程不同,这种方法是解决这种问题的通法