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
这个题就是让求,把一个数字因数分解,将因数写成一列,要求后一个数字能被前一个数字整除。问这样的因子链中最长的链有多少个。
做法就是将该数字因式分解,分解成质因子。所有的质因子相乘能得到这个数字。那么只取其中的一些因子相乘也必定能整除这个数。
像 100 可以分解为 2*2*5*5
就可以写成 2-(2*2)-(2*2*5)-(2*2*5*5) 这样一条链
然后排列组合算种类数
所以最终是求一个数的不重复的质因子的全排列。
最开始看到给的数据范围是2^20次方,然后傻傻的建了一个很大的数组晒素数。。。肯定筛不出来的。。。后来才想到,因式分解,最多只要除到这个数的平方根就好了,根本不用筛那么多素数,,,TAT。。。
所以这个题只要筛到2^10=1024就够了,,,建个1100的数组就够用了。
在分解质因数的时候,也要注意遍历的范围停止条件,缩小范围。
这样会快很多。
#include<iostream>
#include<cstring>
#include<map>
#define SIZE 11000
using namespace std;
long long p[SIZE + 1];
void prime()//筛素数
{
int i, j, k, t;
memset(p, 0, sizeof(p));
for (i = 2; i <= SIZE; i++)
{
if (!p[i])
for (j = i + 1; j <= SIZE; j++)
if (j%i == 0) p[j] = 1;
}
}
long long d(int n)//阶乘
{
long long sum = 1;
for (int i = n; i > 0; i--)
sum *= i;
return sum;
}
void f(int n)
{
int i, ct;
long long sum;
int s = n;
map<int, int> a;//存储素因数的个数
map<int, int>::iterator it;
ct = 0;
while (s % 2 == 0)//只有2是偶素数先把偶数筛掉,后面只用筛奇数,i=i+2,比较快
{
ct++;
if (a[2])
a[2]++;
else a[2] = 1;
s /= 2;
}
for (i = 3; i*i <= s&&i <= SIZE;)//奇素数
{
if (!p[i])
{
if (s%i == 0)
{
s /= i;
if (a[i])
a[i]++;
else a[i] = 1;
ct++;
}
else i = i + 2;
}
else i = i + 2;
}
if (s != 1)
{
ct++;
if (a[s])
a[s]++;
else a[s] = 1;
}
for (it = a.begin(), sum = 1; it != a.end(); it++)
sum *= d(it->second);
cout << ct << " " << d(ct) / sum << endl;
}
int main()
{
int T;
int i, j, k, t;
bool flag;
prime();
while (cin >> T)
{
flag = false;
for (i = 2; i <= SIZE&&i*i <= T&&flag == false; i++)
{
if (T%i == 0)
{
f(T);//不是素数
flag = true;
break;
}
}
if (flag == false && T != 1)//是素数
cout << "1 1" << endl;
else if (flag == false && T == 1)//该数字为1
cout << "0 1" << endl;
}
return 0;
}