#ySybttg060305. 1629:聪明的燕姿
1629:聪明的燕姿
1629:聪明的燕姿
题目描述
城市中人们总是拿着号码牌,不停寻找,不断匹配,可是谁也不知道自己等的那个人是谁。
可是燕姿不一样,燕姿知道自己等的人是谁,因为燕姿数学学得好!燕姿发现了一个神奇的算法:假设自己的号码牌上写着数字 ,那么自己等的人手上的号码牌数字的所有正约数之和必定等于 。
所以燕姿总是拿着号码牌在地铁和人海找数字(喂!这样真的靠谱吗)可是她忙着唱《绿光》,想拜托你写一个程序能够快速地找到所有自己等的人。
输入格式
输入包含 组数据。
对于每组数据,输入包含一个号码牌 。
输出格式
对于每组数据,输出有两行,第一行包含一个整数 ,表示有 个等的人。
第二行包含相应的 个数,表示所有等的人的号码牌。
注意:你输出的号码牌必须按照升序排列。
样例
样例输入 #1
42
样例输出 #1
3
20 26 41
样例解释 #1
- 输入 。
- 寻找所有正整数 ,使得 的所有正约数之和等于 。
- 满足条件的 有 :
- 的约数:,和 。
- 的约数:,和 。
- 的约数:,和 。
- 输出 ,然后升序输出 。
数据范围
对于 的数据,,。
时空限制
- 时间限制:1000 ms
- 内存限制:524288 KB
注意:本题是已知约数和 ,求所有满足条件的数 。设 ,则其约数和 $\sigma(n) = \prod_{i=1}^k (1 + p_i + p_i^2 + \cdots + p_i^{a_i}) = \prod_{i=1}^k \frac{p_i^{a_i+1} - 1}{p_i - 1}$。
问题转化为:将 分解成若干个因子 的乘积,其中 是质数,。我们需要搜索所有可能的分解方式,然后计算出对应的 。
由于 ,,我们可以预处理所有小于等于 的质数(实际上需要更大一些,因为 可能大于 ,但此时 ,因子为 )。搜索时,从最小的质数开始枚举,尝试将 除以 (其中 从 开始递增,直到该值大于 ),递归搜索。注意剪枝:如果当前剩余的 减 后是质数且大于当前质数,则得到一种解(因为 形式)。
具体步骤:
- 预处理质数表(至少到 )。
- DFS 搜索,参数:当前剩余值 ,当前最小质数下标 ,当前累积值 。
- 如果 ,则找到一个解 ,加入答案集合。
- 否则,从 开始枚举质数 ,对于每个 ,枚举指数 从 开始,计算 ,如果 则 break。如果 ,则递归搜索 ,,下一个质数从 的下一个开始(因为质数递增,避免重复)。
- 此外,如果 是质数且 (避免重复),则得到解 (因为 ,对应 )。
- 注意 和 可能超过
long long范围,需要判断溢出。
最后,将答案排序输出。注意 时, 的约数和为 ,但 可能不是“号码牌”?题目要求“号码牌数字”,应该可以是 吧?但样例中 没有 ,因为 的约数和为 。需要看题目是否允许 。通常 的约数和是 ,如果 则 是一个解。但题目中 ?没有明确,但 , 可能为 。需要处理。
由于 , 最大 ,搜索不会太深。注意去重和排序。