dfs
跟上道题很像有木有
同样地,我们暴力枚举约数
根据约数和公式,得出$S=\prod_{i=1}^{n}{(1+p+p^{2}+...+p^{a_{i}})}$
所以每次我们暴力枚举是哪个约数,次数是多少,然后爆搜
如果剩下的约数和$S-1$是质数,那么说明约数只剩下一个大质数,直接统计答案结束即可
因为一个数不可能大于自己的约数和,所以大于$sqrt(S)$的约数只能有一个
#include<bits/stdc++.h> using namespace std; const int N = 5e4 + 5; int s, sqrts; int p[N], mark[N], ans[N << 1]; void shaker() { for(int i = 2; i < N; ++i) { if(!mark[i]) { p[++p[0]] = i; } for(int j = 1; j <= p[0] && i * p[j] < N; ++j) { mark[i * p[j]] = 1; if(i % p[j] == 0) { break; } } } } bool judge(int x) { if(x == 1) { return 0; } if(x < N) { return !mark[x]; } for(int i = 1; p[i] * p[i] <= x; ++i) { if(x % p[i] == 0) { return 0; } } return 1; } void dfs(int last, int tot, int sum) { if(tot == 1) { ans[++ans[0]] = sum; return; } if(tot - 1 > sqrts && judge(tot - 1)) { ans[++ans[0]] = sum * (tot - 1); } for(int i = last + 1; p[i] <= sqrts; ++i) { int t = p[i], all = 1; for(int j = 1; all + t <= tot; ++j) { all += t; if(tot % all == 0) { dfs(i, tot / all, sum * t); } t *= p[i]; } } } int main() { shaker(); while(scanf("%d", &s) != EOF) { ans[0] = 0; sqrts = sqrt(s); dfs(0, s, 1); sort(ans + 1, ans + ans[0] + 1); printf("%d\n", ans[0]); for(int i = 1; i < ans[0]; ++i) { printf("%d ", ans[i]); } if(ans[0]) { printf("%d\n", ans[ans[0]]); } } return 0; }