poj3421 X-factor Chains

还是比较简单的233

发现质因数分解之后就是每次乘一个质因数组成的链

所以链长质因数分解之后指数相加即可

方案数就是当前剩几种就推一位

但是显然不能递推 发现组合一下就是组合数(n,m) * (n-m,k) * (n-m-k,r) * .... * (lst,0)

再组合一下就是和的阶乘除以阶乘的和

发现和最多是20不会爆ll 于是AC

Code:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
#define ms(a,b) memset(a,b,sizeof a)
#define rep(i,a,n) for(int i = a;i <= n;i++)
#define per(i,n,a) for(int i = n;i >= a;i--)
#define inf 2147483647
using namespace std;
typedef long long ll;
ll read() {
    ll as = 0,fu = 1;
    char c = getchar();
    while(c < '0' || c > '9') {
        if(c == '-') fu = -1;
        c = getchar();
    }
    while(c >= '0' && c <= '9') {
        as = as * 10 + c - '0';
        c = getchar();
    }
    return as * fu;
}
const int N = 2000005;
//head

int mindiv[N],prime[83000];
void initprime(int n) {
    rep(i,2,n) {
    if(!mindiv[i]) prime[++prime[0]] = i;
    for(int j = 1;j <= prime[0] && i * prime[j] <= n;j++) {
        mindiv[i * prime[j]] = prime[j];
        if(i % prime[j] == 0) break;
    }
    }
}
ll fac[N];
void initfac(int n) {
    fac[0] = 1;
    rep(i,1,n) fac[i] = fac[i-1] * i;
}

int val[22];
int sum;
ll ans;
void div(int n) {
    rep(i,1,prime[0]) {
    int tmp = 0;
    while(n % prime[i] == 0) {
        n /= prime[i];
        tmp++;
    }
    sum += tmp;
    val[tmp]++;
    if(n == 1) break;
    }
}

int main() {
    int n;
    initprime(1<<20);
    initfac(21);
    while(~scanf("%d",&n)) {
    sum = 0;
    ms(val,0);
    if(n == 1) {
        printf("1 1
");
        continue;
    }
    div(n);
    printf("%d ",sum);
    ans = fac[sum];
    rep(i,1,20) while(val[i]) ans /= fac[i],val[i]--;
    printf("%lld
",ans);
    
    }
    return 0;
}
View Code
> 别忘了 总有人在等着你
原文地址:https://www.cnblogs.com/yuyanjiaB/p/9777765.html