BZOJ 3629[JLOI2014]聪明的燕姿

3629: [JLOI2014]聪明的燕姿

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 1386  Solved: 507
[Submit][Status][Discuss]

Description

阴天傍晚车窗外
未来有一个人在等待
向左向右向前看
爱要拐几个弯才来
我遇见谁会有怎样的对白
我等的人他在多远的未来
我听见风来自地铁和人海
我排着队拿着爱的号码牌
城市中人们总是拿着号码牌,不停寻找,不断匹配,可是谁也不知道自己等的那个人是谁。可是燕姿不一样,燕姿知道自己等的人是谁,因为燕姿数学学得好!燕姿发现了一个神奇的算法:假设自己的号码牌上写着数字S,那么自己等的人手上的号码牌数字的所有正约数之和必定等于S。
所以燕姿总是拿着号码牌在地铁和人海找数字(喂!这样真的靠谱吗)可是她忙着唱《绿光》,想拜托你写一个程序能够快速地找到所有自己等的人。

Input

输入包含k组数据(k<=100)对于每组数据,输入包含一个号码牌S

Output

对于每组数据,输出有两行,第一行包含一个整数m,表示有m个等的人,第二行包含相应的m个数,表示所有等的人的号码牌。注意:你输出的号码牌必须按照升序排列。

Sample Input

42

Sample Output

3
20 26 41

HINT

对于100%的数据,有S<=2*10*9

由唯一分解定理:

ans=p1^k1*p2^k2……pn^kn

n=(1+p1+……+p1^k1)*(1+p2+……+p2^k2)*……*(1+pn+……+pn^kn)

可以深搜枚举质数,判断是否是n的因子。

注意特判。

 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<math.h>
 4 #include<algorithm>
 5 using namespace std;
 6 #define maxn 100000
 7 #define LL long long 
 8 int p[maxn+1],cnt;
 9 bool book[maxn+1];
10 int t,num;
11 int ans[200001];
12 void init()
13 {
14     for(int i=2;i<=maxn;i++)
15     {
16         if(!book[i])
17             p[++cnt]=i;
18         for(int j=1;j<=cnt&&p[j]*i<=maxn;j++)
19         {
20             book[i*p[j]]=true;
21             if((i%p[j])==0) 
22                 break;
23         }
24     }
25 }
26 bool judge(int x)
27 {
28     if(x==1)
29         return false;
30     if(x<=maxn)
31         return !book[x];
32     for(int i=1;p[i]*p[i]<=x;i++)
33         if(x%p[i]==0)
34             return false;
35     return true;
36 }
37 void dfs(LL s,int pos,LL x)
38 {   
39     if(s==1)
40     {
41         ans[++num]=x;
42         return ;
43     }
44     if(judge(s-1)&&s-1>=p[pos])
45         ans[++num]=x*(s-1);
46     LL sum,indx;
47     for(int i=pos;p[i]*p[i]<=s;i++)
48     {
49         sum=p[i]+1;
50         indx=p[i];
51         for(;sum<=s;indx*=p[i],sum+=indx)
52             if(s%sum==0)
53                 dfs(s/sum,i+1,x*indx);
54     }
55 }
56 int n;
57 int main()
58 {
59     init();
60     while(scanf("%d",&n)!=EOF)
61     {
62         dfs(n,1,1);
63         printf("%d
",num);
64         if(num)
65         {   
66             sort(ans+1,ans+num+1);
67             for(int i=1;i<=num;i++)
68                 printf("%d%c",ans[i],i==num?'
':' ');
69             num=0;
70         }
71     }
72 }
BZOJ 3629

(PS:BZOJ卡输出空格,miller_rabin判断不是TLE就是WA)

原文地址:https://www.cnblogs.com/radioteletscope/p/7147694.html