X-factor Chains
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 9796 Accepted: 3164
Description
Given a positive integer X, an X-factor chain of length m is a sequence of integers,
1 = X0, X1, X2, …, Xm = X
satisfying
Xi < Xi+1 and Xi | Xi+1 where a | b means a perfectly divides into b.
Now we are interested in the maximum length of X-factor chains and the number of chains of such length.
Input
The input consists of several test cases. Each contains a positive integer X (X ≤ 220).
Output
For each test case, output the maximum length and the number of such X-factors chains.
Sample Input
2
3
4
10
100
Sample Output
1 1
1 1
2 1
2 2
4 6
分析:
任意一个正整数 x x x 可以被分解为 ∏ p i e i \prod{p_{i}^{e_{i}}} ∏piei 的形式,其中 p i p_i pi 是质数,而质数不能再被分解,所以最长的链的长度就是 ∑ e i \sum{e_i} ∑ei ,即所有质因子的个数(计算重复的个数)。而这个最长链的种类数则是所有质因子的排列的种类数,可以利用高中的组合数学公式 S = A ∑ e i ∑ e i ∏ A e i e i S=\frac{A_{\sum{e_i}}^{\sum{e_i}}}{\prod{A_{e_i}^{e_i}}} S=∏AeieiA∑ei∑ei 计算出。
下面贴代码:
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
const int MAX_N = 21;
typedef long long ll;
bool is_prime[1 << MAX_N / 2];
int primes[1 << MAX_N / 2];
int pcnt;
ll A[MAX_N];
int factor[MAX_N], cnt[MAX_N];
void init();
void getprime(const int N);
int main()
{
init();
int x;
while (~scanf("%d", &x))
{
int tot = 0, ans = 0;
int sqx = sqrt((double)x) + 1;
memset(cnt, 0, sizeof(cnt));
for (int i = 0; i < pcnt && primes[i] < sqx; ++i)
{
const int& cur = primes[i];
if (!(x % cur))
{
factor[tot] = cur;
while (!(x % cur))
{
x /= cur;
++cnt[tot];
++ans;
}
++tot;
sqx = sqrt((double)x) + 1;
}
}
if (x > 1)
{
factor[tot] = x;
cnt[tot++] = 1;
++ans;
}
ll ans2 = A[ans];
while (tot--)
{
ans2 /= A[cnt[tot]];
}
printf("%d %lld\n", ans, ans2);
}
return 0;
}
void init()
{
getprime(1 << MAX_N / 2);
A[0] = 1;
for (int i = 1; i < MAX_N; ++i)
{
A[i] = i * A[i - 1];
}
}
void getprime(const int N)
{
for (int i = 2; i < N; ++i)
{
if (!is_prime[i])
{
primes[pcnt++] = i;
for (int j = i << 1; j < N; j += i)
{
is_prime[j] = true;
}
}
}
}