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 ",ans); } return 0; }