[BZOJ3629][JLOI2014]聪明的燕姿(数论+搜索)

Address

https://www.lydsy.com/JudgeOnline/problem.php?id=3629

Solution

根据小学知识,如果一个正整数 n 的标准分解形式为 n = i = 1 m p i q i ,那么 n 的约数和为:

i = 1 m ( 1 + p i + p i 2 + . . . + p i q i ) = i = 1 m p i q i + 1 1 p i 1

我们可以大力搜索每个质因数的出现次数。
不过有一些技巧,否则 TLE :
(1)大于 n 的因子最多一个,因此搜完 n 以内的质因子且当前讨论到 n u m 时,只需要判断是否 n u m | n n n u m 大于 n 且为质数即可。当然,如果 n u m = n 就无须讨论这一点。
(2)尽管 n 的约数不是很多,但我们还是可以构造出一些 n 使 m 比较大,比如 12 ! 。为了降低复杂度,我们还需要将 n 以内的质数 从大到小枚举,避免 dfs 时在无解的节点上浪费过多时间。

Code

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define For(i, a, b) for (i = a; i <= b; i++)
using namespace std;
const int N = 1e6 + 5, M = 5e4 + 5;
int n, m, len, ans[N], MaxN, tot, pri[M];
bool mark[N];
inline bool Pri(const int &n) {
    int i, S = sqrt(n);
    For (i, 2, S) if (n % i == 0) return 0;
    return 1;
}
void sieve() {
    int i, j;
    MaxN = sqrt(n);
    For (i, 0, 50000) mark[i] = 0;
    mark[0] = mark[1] = 1;
    For (i, 2, 50000) {
        if (!mark[i]) {
            pri[++tot] = i;
            if (i <= MaxN) len = tot;
        }
        For (j, 1, tot) {
            if (1ll * i * pri[j] > 1000000) break;
            mark[i * pri[j]] = 1;
            if (i % pri[j] == 0) break;
        }
    }
}
inline void dfs(const int &dep, const int &num, const int &sum) {
    if (sum == n) return (void) (ans[++m] = num);
    if (dep == len + 1) {
        if (n / sum - 1 > MaxN && Pri(n / sum - 1))
            ans[++m] = num * (n / sum - 1);
        return;
    }
    int i, s = 1, q = 1;
    For (i, 0, 998244353) {
        if (n % (s * sum) == 0) dfs(dep + 1, num * q, sum * s);
        if ((1ll * q * pri[len - dep + 1] + s) * sum > n) break;
        s += (q *= pri[len - dep + 1]);
    }
}
void work() {
    int i; m = tot = 0;
    sieve();
    dfs(1, 1, 1);
    printf("%d\n", m);
    sort(ans + 1, ans + m + 1);
    For (i, 1, m) printf("%d ", ans[i]);
    if (m) printf("\n");
}
int main() {
    while (~scanf("%d", &n)) work();
    return 0;
}

猜你喜欢

转载自blog.csdn.net/xyz32768/article/details/81457901