有点神奇。
膜拜一发【wulala的题解】
/* Footprints In The Blood Soaked Snow */
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
typedef unsigned long long ULL;
const int maxn = 50005;
int n, cnt, prime[maxn], ans[maxn], tot;
bool isnotprime[maxn];
inline void getprime() {
for(int i = 2; i < maxn; i++) {
if(!isnotprime[i]) prime[++cnt] = i;
for(int j = 1; j <= cnt && i * prime[j] < maxn; j++) {
isnotprime[i * prime[j]] = 1;
if(i % prime[j] == 0) break;
}
}
}
inline bool checkprime(int x) {
if(x == 1) return 0;
for(int i = 1; i <= cnt && prime[i] * prime[i] <= x; i++)
if(x % prime[i] == 0) return 0;
return 1;
}
inline void dfs(int now, ULL pro, ULL left) {
if(left == 1) {
ans[++tot] = pro;
return;
}
if(prime[now] <= left - 1 && checkprime(left - 1))
ans[++tot] = (left - 1) * pro;
for(int i = now; prime[i] * prime[i] <= left; i++)
for(ULL res = prime[i], div = prime[i] + 1; div <= left; res *= prime[i], div += res)
if(left % div == 0)
dfs(i + 1, pro * res, left / div);
}
int main() {
getprime();
while(scanf("%d", &n) != EOF) {
tot = 0;
dfs(1, 1, n);
sort(ans + 1, ans + 1 + tot);
printf("%d\n", tot);
for(int i = 1; i < tot; i++) printf("%d ", ans[i]);
if(tot) printf("%d\n", ans[tot]);
}
return 0;
}
一开始写了一发质因数分解暴力,最后发现还不如普通n√n快。
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
typedef unsigned long long ULL;
const int maxn = 50005;
int n, cnt, prime[maxn], ans[maxn], tot;
bool isnotprime[maxn];
inline void getprime() {
for(int i = 2; i < maxn; i++) {
if(!isnotprime[i]) prime[++cnt] = i;
for(int j = 1; j <= cnt && i * prime[j] < maxn; j++) {
isnotprime[i * prime[j]] = 1;
if(i % prime[j] == 0) break;
}
}
}
inline void dfs(int now, ULL pro, int sum) {
if(pro > n || prime[now] > n) return;
if(pro == n) {
ans[++tot] = sum;
return;
}
if(sum == 1 && prime[now] + 1 == n) {
ans[++tot] = prime[now];
return;
}
if(now > cnt) return;
ULL pre = 1, div = 1;
while(pro <= n && sum <= n) {
dfs(now + 1, pro * div, sum);
sum *= prime[now];
pre *= prime[now];
div += pre;
}
}
int main() {
getprime();
while(scanf("%d", &n) != EOF) {
tot = 0;
dfs(1, 1, 1);
sort(ans + 1, ans + 1 + tot);
printf("%d\n", tot);
for(int i = 1; i < tot; i++) printf("%d ", ans[i]);
if(tot) printf("%d\n", ans[tot]);
}
return 0;
}