POJ3421 X-factor Chains - 数论 - 质因子分解 + 排列组合

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 可以被分解为 p i e i \prod{p_{i}^{e_{i}}} 的形式,其中 p i p_i 是质数,而质数不能再被分解,所以最长的链的长度就是 e i \sum{e_i} ,即所有质因子的个数(计算重复的个数)。而这个最长链的种类数则是所有质因子的排列的种类数,可以利用高中的组合数学公式 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}}} 计算出。

 
 
下面贴代码:

#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;
			}
		}
	}
}

原创文章 42 获赞 22 访问量 3048

猜你喜欢

转载自blog.csdn.net/weixin_44327262/article/details/97770900