『算法-ACM 竞赛-数学-数论』HDU 12151 七夕节 Plus (因子和线性筛)
Problem Description
1 2
| 七夕节那天,月老来到数字王国,他在城门上贴了一张告示,并且和数字王国的人们说:"你们想知道你们的另一半是谁吗?那就按照告示上的方法去找吧!" 人们纷纷来到告示前,都想知道谁才是自己的另一半.告示如下:
|
1 2
| 数字N的因子就是所有比N小又能被N整除的所有正整数,如12的因子有1,2,3,4,6. 你想知道你的另一半吗?
|
Input
1
| 输入数据的第一行是一个数字T(1<=T<=500000),它表明测试数据的组数.然后是T组测试数据,每组测试数据只有一个数字N(1<=N<=500000).
|
Output
1
| 对于每组测试数据,请输出一个代表输入数据N的另一半的编号.
|
Sample Input
Sample Output
之前是纯暴力写的,现在直到因子和是积性函数,直接一个筛法搞定。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| #include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #include <queue> #include <stack> #include <map> #include <vector> #include <string> using namespace std; typedef long long ll; #define N 500022 int prime[N],cnt; bool vis[N]; int num[N],e[N]; void init() { for(int i=2;i<=N;++i) { if(!vis[i]) { prime[++cnt]=i; num[i]=i+1; e[i]=1; } for(int j=1;j<=cnt;++j) { if(prime[j]*i>N) break; vis[prime[j]*i]=true; if(i%prime[j]==0) { num[i*prime[j]]=num[i]*prime[j]+e[i]; e[i*prime[j]]=e[i]; break; } num[i*prime[j]]=num[i]*(prime[j]+1); e[i*prime[j]]=num[i]; } } } int main() { int T; init(); scanf("%d",&T); while(T--) { int n; scanf("%d",&n); printf("%lld\n",num[n]-(long long )n); } }
|