1. 程式人生 > >POJ3421:X-factor Chains——題解

POJ3421:X-factor Chains——題解

span esp org namespace div name ret 因數 題解

http://poj.org/problem?id=3421

題目大意:一個數列,起始為1,終止為一給定數X,滿足Xi < Xi+1 並且Xi | Xi+1

求出數列最大長度和該長度下的情況數。

——————————————

很簡單想到分解X質因數,這樣我們每加一個數就是前一個數*其中一個質因數即可。

所以長度為質因數個數。

至於情況數,就是有重復的排列數,去重即可求。

(不開longlong見祖宗,十年OI一場空)

#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
typedef long long ll;
using namespace std;
int su[1025];
bool he[1025];
ll t[1025];
int cnt=0;
ll sum=0;
void Euler(int n){
    for(int i=2;i<=n;i++){
    if(he[i]==0
){ cnt++; su[cnt]=i; } for(int j=1;j<=cnt&&i*su[j]<=n;j++){ he[su[j]*i]=1; if(i%su[j]==0)break; } } return; } void fen(ll x){ for(int i=1;i<=cnt&&su[i]*su[i]<=x;i++){ ll p=su[i]; if(x%p==0){
while(x%p==0){ sum++; t[i]++; x/=p; } } } if(x>1)sum++; return; } ll jie(int k){ ll ans=1; for(int i=2;i<=k;i++){ ans*=i; } return ans; } int main(){ Euler(1024); ll x; while(scanf("%lld",&x)!=EOF){ if(x==0)break; memset(t,0,sizeof(t)); sum=0; fen(x); printf("%lld ",sum); ll ans=jie(sum); for(int i=1;i<=cnt;i++){ ans/=jie(t[i]); } printf("%lld\n",ans); } return 0; }

POJ3421:X-factor Chains——題解