HDU

来源:互联网 发布:买家怎样修改淘宝评价 编辑:程序博客网 时间:2024/06/10 07:21

题目:

Given a number sequence b 1,b 2…b n
Please count how many number sequences a 1,a 2,...,a n satisfy the condition that a1*a 2*...*a n=b 1*b 2*…*b n (a i>1).

Input
The input consists of multiple test cases. 
For each test case, the first line contains an integer n(1<=n<=20). The second line contains n integers which indicate b 1, b 2,...,b n(1<b i<=1000000, b 1*b 2*…*bn<=10 25).
Output
For each test case, please print the answer module 1e9 + 7.
Sample Input
23 4
Sample Output
4

Hint
For the sample input, P=3*4=12.Here are the number sequences that satisfy the condition:2 63 44 36 2


思路:把每个质因数出现的次数统计出来,假设质数pi,出现的次数为m次,那么就相当于把m个东西放入n个容器中,但是不允许都为空,如果不管是否为空,那么选择的方法有c(n+m-1,n-1)种,然后算出总的方法数,用容斥定理减去不合法的方法数。

代码:

#pragma comment(linker, "/STACK:1024000000,1024000000")#include<iostream>#include<algorithm>#include<ctime>#include<cstdio>#include<cmath>#include<cstring>#include<string>#include<vector>#include<map>#include<set>#include<queue>#include<stack>#include<list>#include<numeric>using namespace std;#define LL long long#define ULL unsigned long long#define INF 1000000000000#define mm(a,b) memset(a,b,sizeof(a))#define PP puts("*********************");template<class T> T f_abs(T a){ return a > 0 ? a : -a; }template<class T> T gcd(T a, T b){ return b ? gcd(b, a%b) : a; }template<class T> T lcm(T a,T b){return a/gcd(a,b)*b;}// 0x3f3f3f3f3f3f3f3f// 0x3f3f3f3fconst LL MOD=1e9+7;const int maxn=1e6+50;bool isprime[maxn];int prime[maxn],tol;void make_prime(int n){    for(int i=0;i<=n;i++)        isprime[i]=true;    isprime[0]=isprime[1]=false;    tol=0;    for(int i=2;i<=n;i++){        if(isprime[i])            prime[tol++]=i;        for(int j=0;j<tol;j++){            if(i*prime[j]<=n)                isprime[i*prime[j]]=false;            else                break;            if(i%prime[j]==0)                break;        }    }}vector<int> fac;int num[405],b[25];LL c[1005][1005];LL C(int n,int m){    return c[n+m-1][n-1];}int main(){    int n;    make_prime(maxn-50);    for(int i=0;i<=1000;i++)        c[i][0]=c[i][i]=1;    for(int i=1;i<=1000;i++)        for(int j=1;j<i;j++)            c[i][j]=(c[i-1][j-1]+c[i-1][j])%MOD;    while(~scanf("%d",&n)){        fac.clear();        for(int i=0;i<n;i++)            scanf("%d",&b[i]);        for(int i=0;i<n;i++){            int x=b[i];            for(int j=0;j<tol&&prime[j]*prime[j]<=b[i];j++){                while(x%prime[j]==0){                    fac.push_back(prime[j]);                    x/=prime[j];                }            }            if(x>1) fac.push_back(x);        }        sort(fac.begin(),fac.end());        mm(num,0);        int cnt=0;        for(int i=0;i<fac.size();i++){            if(i==0)                num[++cnt]=1;            else{                if(fac[i]==fac[i-1]) num[cnt]++;                else num[++cnt]=1;            }        }        LL ans=1;        for(int i=1;i<=cnt;i++)            ans=(ans*C(n,num[i]))%MOD;        for(int i=1;i<=n-1;i++){//枚举空容器的个数            LL tmp=c[n][i];            for(int j=1;j<=cnt;j++)                tmp=(tmp*C(n-i,num[j]))%MOD;//            printf("%d  %lld\n",i,tmp);            if(i%2==1){                ans=(ans-tmp)%MOD;                ans=(ans+MOD)%MOD;            }            else                ans=(ans+tmp)%MOD;        }        printf("%lld\n",ans);    }    return 0;}


原创粉丝点击