「JLOI2014」聪明的燕姿
Posted zsbzsb
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了「JLOI2014」聪明的燕姿相关的知识,希望对你有一定的参考价值。
传送门
Luogu
解题思路
很容易想到直接构造合法的数,但是这显然是会T飞的。
我们需要考虑这样一件事:
对于一个数 (n),对其进行质因数分解:
[n=sum_{i=1}^x p_i^{c_i}]
那么就会有:
[sigma(n)=prod_{i=1}^x sum_{j=1}^{c_i}p^j]
可以证明 (sigma(n)) 和 (n) 同级,所以这个质因子 (p_ile sqrt{S}),所以我们可以直接爆搜出来所有小于 (sqrt{S}) 的质数,特判一下每一层dfs时的 (S-1) 是否为质数,然后算答案。
细节注意事项
- 爆搜题,你们懂得。。。
参考代码
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cctype>
#include <cmath>
#include <ctime>
#define rg register
using namespace std;
template < typename T > inline void read(T& s) {
s = 0; int f = 0; char c = getchar();
while (!isdigit(c)) f |= c == '-', c = getchar();
while (isdigit(c)) s = s * 10 + (c ^ 48), c = getchar();
s = f ? -s : s;
}
int vis[50000], num, prime[50000];
int cnt, ans[500000];
inline void seive() {
vis[1] = 1;
for (rg int i = 2; i < 50000; ++i) {
if (!vis[i]) prime[++num] = i;
for (rg int j = 1; j <= num && i * prime[j] < 50000; ++j) {
vis[i * prime[j]] = 1;
if (i % prime[j] == 0) break;
}
}
}
inline bool isprime(int x) {
if (x <= 1) return 0;
if (x == 2) return 1;
for (rg int i = 2; i * i <= x; ++i)
if (x % i == 0) return 0;
return 1;
}
inline void dfs(int x, int i, int s) {
if (x == 1) { ans[++cnt] = s; return; }
if (isprime(x - 1) && x > prime[i]) ans[++cnt] = s * (x - 1);
for (rg int j = i; prime[j] * prime[j] <= x; ++j) {
int last = prime[j], sum = prime[j] + 1;
for (; sum <= x; last *= prime[j], sum += last)
if (x % sum == 0) dfs(x / sum, j + 1, s * last);
}
}
inline void solve(int x) {
if (x == 1) { puts("1"), puts("1"); return ; }
cnt = 0, dfs(x, 1, 1);
printf("%d
", cnt);
sort(ans + 1, ans + cnt + 1);
for (rg int i = 1; i <= cnt; ++i)
printf("%d%c", ans[i], "
"[i == cnt]);
}
int main() {
#ifndef ONLINE_JUDGE
freopen("in.in", "r", stdin);
#endif
seive();
int n;
while (scanf("%d", &n) != EOF) solve(n);
return 0;
}
完结撒花 (qwq)
以上是关于「JLOI2014」聪明的燕姿的主要内容,如果未能解决你的问题,请参考以下文章
bzoj 3629 [JLOI2014]聪明的燕姿(约数和,搜索)
bzoj 3629: [JLOI2014]聪明的燕姿线性筛+dfs