http://poj.org/problem?id=3421
X-factor Chains
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 4495 | Accepted: 1379 |
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
Source
解法:
s=p1^a1*p2^a2*p3^a3.....pn^an, 其中p1..pn为素数因为素数不可再分,所以最大值为 (a1+a2+...+an)的最大值。所以就看s能分解成几个素数的k次方。所求得的数利用排列组合算下组合数即为最大长度的数量组合数为 :(a1+a2...an)!/(a1!*a2!...*an!)
/*************************************************
* 核心原理:
* s=p1^a1*p2^a2*p3^a3.....pn^an, 其中p1..pn为素数
**************************************************/
#include<cstdio>
#include<cstring>
#include <cmath>
const int M=(1<<20)+5;
bool is[M];
int prim[M>>1];
int a[100],k;
int getprm(int n)
{
int i, j, k = 0;
int s, e = (int)(sqrt(0.0 + n) + 1);
memset(is, 1, sizeof(is));
prim[k++] = 2; is[0] = is[1] = 0;
for (i = 4; i < n; i += 2) is[i] = 0;
for (i = 3; i < e; i += 2) if (is[i]) {
prim[k++] = i;
for (s = i * 2, j = i * i; j < n; j += s)
is[j] = 0;
// 因为j是奇数,所以+奇数i后是偶数,不必处理!
}
for ( ; i < n; i += 2) if (is[i]) prim[k++] = i;
return k; // 返回素数的个数
}
int main()
{
int i,t,k,sum1,j,n;
__int64 sum2;
t=getprm(M);
while(scanf("%d",&n)==1)
{
if(is[n])
{
printf("1 1\n");
continue;
}
k=0;
for(i=0;i<t;i++)
{
if (n==1)
break;
if (n%prim[i]==0)
{
a[k]=0;
while(n%prim[i]==0)
n/=prim[i],a[k]++; //p[k]=count(ak)
k++;
}
}
sum1=0;
for(i=0;i<k;i++) //sum1 = a1+a2..+an
sum1+=a[i];
sum2=1;
for(i=1;i<=sum1;i++)
sum2*=i;
for(i=0;i<k;i++) //sum2 = (a1+a2...an)!/(a1!*a2!...*an!)
for(j=2;j<=a[i];j++)
sum2/=j;
printf("%d %I64d\n",sum1,sum2);
}
return 0;
}