60分代码,4个TLE,我是枚举的质数次数,请问除了换成枚举质数(第一篇题解)如何才能提高搜索效率呢?
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 5 * 1e4 + 1919, N = 5 * 1e4;
typedef long long LL;
const LL INF = 2000000000ll;
int prime[MAXN], v[MAXN], num;
LL S;
LL power[MAXN][39], ans[MAXN];
int max_pow[MAXN], c[MAXN];
void prepare() {
for (int i = 2; i <= N; i++) {
if (!v[i]) {
v[i] = i;
prime[++num] = i;
}
for (int j = 1; j <= num; j++) {
if (prime[j] > v[i] || prime[j] * i > N)
break;
v[prime[j] * i] = prime[j];
}
}
for (int i = 1; i <= num; i++) {
int p = prime[i];
power[i][0] = 1;
for (int j = 1; j <= 31; j++) {
power[i][j] = power[i][j - 1] * p;
if (power[i][j - 1] * p > INF) {
max_pow[i] = j - 1;
break;
}
}
}
}
inline bool pd(LL x) {
if (x == 1)
return false;
for (LL i = 2; i * i <= x; i++)
if (x % i == 0)
return false;
return true;
}
inline LL calc(int t, int ci) { return (power[t][ci + 1] - 1) / (prime[t] - 1); }
int m;
void dfs(int t, LL now, LL now_ans) {
if (now == 1ll) {
ans[++m] = now_ans;
return;
}
if (t == num) {
if (pd(now - 1) && now > prime[t]) {
ans[++m] = now_ans * (now - 1);
}
return;
}
for (int i = 0; i <= max_pow[t]; i++) {
LL cal = calc(t, i);
if (cal > now) break;
if (now % cal == 0) {
c[t] = i;
dfs(t + 1, now / cal, now_ans * power[t][c[t]]);
c[t] = 0;
}
}
}
inline void solve() {
m = 0;
dfs(1, S, 1);
sort(ans + 1, ans + m + 1);
cout << m << endl;
if (m) {
for (int i = 1; i <= m; i++) printf("%lld ", ans[i]);
printf("\n");
}
}
int main() {
prepare();
while (scanf("%lld", &S) == 1) {
solve();
}
return 0;
}