2010-1166

从 Trac 迁移的文章

这是从旧校内 Wiki 迁移的文章,可能存在一些样式问题,您可以向 memset0 反馈。

原文章内容如下:

这道题目,首先对于输入n 进行素因数分解,假设有m个素因数(相同的素因数重复计算,比如4的素因数有2个),对于这个m个数的每一种不同的排列,其中不同的Factor Tree的个数就是有m个叶子节点的二叉树个数,也就是m的卡特朗数.

所以这题的答案就是m个有重复数的排列乘上m的卡特朗数。


{{{
#!cpp
#include <cstring>
#include <cstdio>
#include <vector>
using namespace std;


typedef unsigned  long long ll;

typedef vector<int> vi;
vi prime;

ll gao( const vi &a ) {
    ll res=1;
    int m =0;
    for(int i=0;i<a.size();++i){
        m+= a[i];
    }

    for(int i=0;i<a.size();++i){
        for(int j=1;j<=a[i];++j){
            res = res * m / j ;
            --m;
        }
    }
    return res;
}


ll gao( int n , int m ) {

    ll res = 1; 
    for(int i=0;i<m;++i){
        res = res * ( n-i ) / (i+1);
    }
    return res;

}

ll gao( int n) {

    vi p ;
    int t=n;
    int cnt=0;
    int size = prime.size();
    for(int i=0;i<size&&prime[i]*prime[i]<=n;++i){

        int tmp =0;
        while ( t % prime[i] == 0 ) {
            ++tmp;
            t/=prime[i];
        }
        if ( tmp >0 ) p.push_back(tmp);
        cnt+=tmp;
    }

    if (t > 1 ) ++cnt,p.push_back(1);

    ll res = gao(2*cnt-2,cnt-1);
    res/=cnt;

    res *= gao(p);


    return res;

}


void gao(){
    bool  g[31622+1];
    memset(g,true,sizeof(g));

    for(int i = 2; i*i <= 31622; ++i ) if(g[i]){
        for(int j=i*i;j<=31622;j+=i)g[j]=false;
    }

    for(int i=2;i<=31622;++i){
        if ( g[i] ) prime.push_back(i);
    }
}

int main(){

    int n;
    gao();
    while ( scanf("%d",&n)!=EOF ) {
        printf("%llu\n",gao(n));
    }

    return 0;

}


}}}

这道题目,首先对于输入n 进行素因数分解,假设有m个素因数(相同的素因数重复计算,比如4的素因数有2个),对于这个m个数的每一种不同的排列,其中不同的Factor Tree的个数就是有m个叶子节点的二叉树个数,也就是m的卡特朗数.

所以这题的答案就是m个有重复数的排列乘上m的卡特朗数。

#include <cstring>
#include <cstdio>
#include <vector>
using namespace std;
typedef unsigned  long long ll;
typedef vector<int> vi;
vi prime;
ll gao( const vi &a ) {
    ll res=1;
    int m =0;
    for(int i=0;i<a.size();++i){
        m+= a[i];
    }
    for(int i=0;i<a.size();++i){
        for(int j=1;j<=a[i];++j){
            res = res * m / j ;
            --m;
        }
    }
    return res;
}
ll gao( int n , int m ) {
    ll res = 1; 
    for(int i=0;i<m;++i){
        res = res * ( n-i ) / (i+1);
    }
    return res;
}
ll gao( int n) {
    vi p ;
    int t=n;
    int cnt=0;
    int size = prime.size();
    for(int i=0;i<size&&prime[i]*prime[i]<=n;++i){
        int tmp =0;
        while ( t % prime[i] == 0 ) {
            ++tmp;
            t/=prime[i];
        }
        if ( tmp >0 ) p.push_back(tmp);
        cnt+=tmp;
    }
    if (t > 1 ) ++cnt,p.push_back(1);
    ll res = gao(2*cnt-2,cnt-1);
    res/=cnt;
    res *= gao(p);
    return res;
}
void gao(){
    bool  g[31622+1];
    memset(g,true,sizeof(g));
    for(int i = 2; i*i <= 31622; ++i ) if(g[i]){
        for(int j=i*i;j<=31622;j+=i)g[j]=false;
    }
    for(int i=2;i<=31622;++i){
        if ( g[i] ) prime.push_back(i);
    }
}
int main(){
    int n;
    gao();
    while ( scanf("%d",&n)!=EOF ) {
        printf("%llu\n",gao(n));
    }
    return 0;
}