您的位置:首页 > 其它

BZOJ 3629 [JLOI 2014]聪明的燕姿 简单数论

2018-02-24 09:25 330 查看
传送门

思路

参考代码

传送门

思路

  这道题因为要输出具体方案,所以只能搜索。首先得知道一个数的唯一分解:

∏iprii∏ipiri

  然后要知道一个数的因数和:

∏i∑j=0ripji∏i∑j=0ripij

  所以,除非 p=S−1p=S−1,否则 pp 一定是小于 S−−√S 的。我们先处理出小于等于 S−−√S 的质数,然后在其中进行搜索,就没有了。

  需要枚举质数和指数。

参考代码

(码力果然下降了,i + 1 调个半天)

#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <set>
#include <bitset>
#include <list>
typedef long long INT;
using std::cin;
using std::cout;
using std::endl;
INT readIn()
{
INT a = 0;
bool minus = false;
char ch = getchar();
while (!(ch == '-' || (ch >= '0' && ch <= '9'))) ch = getchar();
if (ch == '-')
{
minus = true;
ch = getchar();
}
while (ch >= '0' && ch <= '9')
{
a = a * 10 + (ch - '0');
ch = getchar();
}
if (minus) a = -a;
return a;
}
void printOut(INT x)
{
char buffer[20];
INT length = 0;
if (x < 0)
{
putchar('-');
x = -x;
}
do
{
buffer[length++] = x % 10 + '0';
x /= 10;
} while (x);
do
{
putchar(buffer[--length]);
} while (length);
}

const int maxn = 44722;
int prime[4649];
bool isntPrime[maxn + 5];
void init()
{
isntPrime[1] = true;
for (int i = 2; i <= maxn; i++)
{
if (!isntPrime[i])
prime[++prime[0]] = i;
for (int j = 1, s = i * prime[j]; j <= prime[0] && s <= maxn; j++, s = i * prime[j])
{
isntPrime[s] = true;
if (!(i % prime[j]))
break;
}
}
}
bool IsPrime(int x)
{
if (x <= maxn) return !isntPrime[x];
int to = std::sqrt(x);
for (int i = 2; i <= to; i++)
if (!(x % i)) return false;
return true;
}

int n;
int sqrtN;
int ans[maxn];

void DFS(int cnt, int remain, int mul)
{
if (remain == 1)
{
ans[++ans[0]] = mul;
return;
}
if (remain - 1 > sqrtN && IsPrime(remain - 1))
{
ans[++ans[0]] = mul * (remain - 1);
}
for (int
eee3
i = cnt; i <= prime[0] && prime[i] <= sqrtN; i++)
{
for (INT t = prime[i], sum = 1 + t; sum <= remain; t *= prime[i], sum += t)
{
if (!(remain % sum))
DFS(i + 1, remain / sum, mul * t);
}
}
}

void run()
{
init();
while (cin >> n)
{
ans[0] = 0;
sqrtN = std::sqrt(n);
DFS(1, n, 1);
std::sort(ans + 1, ans + 1 + ans[0]);
printOut(ans[0]);
putchar('\n');
if (ans[0])
{
printOut(ans[1]);
for (int i = 2; i <= ans[0]; i++)
{
putchar(' ');
printOut(ans[i]);
}
putchar('\n');
}
}
}

int main()
{
run();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: