X的因子链
2020-02-10 23:57:58
本文总阅读量

题目

题目链接

题目描述

输入正整数,求的大于的因子组成的满足任意前一项都能整除后一项的严格递增序列的最大长度,以及满足最大长度的序列的个数。

输入格式

输入包含多组数据,每组数据占一行,包含一个正整数表示

输出格式

对于每组数据,输出序列的最大长度以及满足最大长度的序列的个数。

每个结果占一行。

数据范围

输入样例:

2 3 4 10 100

输出样例:

1 1 1 1 2 1 2 2 4 6

分析

算数基本定理:任何一个大于的自然数,如果不为质数,那么可以唯一分解成有限个质数的乘积,这里均为质数,其中指数是正整数。

后一项能整除前一项,即后一项为前一项乘任意一个质因子。最大长度由分解质因数可得,即

本题还问到了满足最长序列的个数,即求所有质因子的全排列,但由于其中有重复的元素,所以转换成多冲击组合数问题。(多重集组合数:一共有种物品,每一种有个,,总共有个物品,则个物品的全排列为

用到的知识

1.算数基本定理以及质因数分解

2.多重集组合数

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

typedef long long LL;

const int N = (1 << 20) + 10;

int x;
int fact[30], sum[30];

LL f(int n)
{
LL res = 1;
for (int i = 1; i <= n; i++)
res *= i;
return res;
}

int main()
{
while (scanf("%d", &x) != EOF)
{
int k = 0;
for (int i = 2; i <= x / i; i++)
{
if (x % i == 0) fact[++k] = i;
while (x % i == 0)
{
sum[k]++;
x /= i;
}
}
if (x != 1) fact[++k] = x, sum[k]++;

int tot = 0;
for (int i = 1; i <= k; i++)
tot += sum[i];

LL res = f(tot);
for (int i = 1; i <= k; i++)
res /= f(sum[i]);

cout << tot << " " << res << endl;

memset(sum, 0, sizeof(sum));
}

return 0;
}