Number Sequence
Time Limit: 10000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Problem Description
Given a number sequence b1,b2…bn. Please count how many number sequences a1,a2,...,an satisfy the condition that a1*a2*...*an=b1*b2*…*bn (ai>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 b1, b2,...,bn(1<bi<=1000000, b1*b2*…*bn<=1025).
Output
For each test case, please print the answer module 1e9 + 7.
Sample Input
2 3 4
Sample Output
4
Hint
For the sample input, P=3*4=12. Here are the number sequences that satisfy the condition:2 6
3 4
4 3
6 2
Source
将每一个数分解质因数,得到每个质因数出现的次数(和质数本身没有关系),然后就要用到容斥原理了,
也就是将每个质数出现的次数放到n个容器中去,这里要注意下1的情况也就是某个容器里面没有放数。
这样结果=总的方案数-有一个容器没放数+有2个容器没有放数……
将m个数放入n个容器的方法数有C(n+m-1,n-1) 。
#include <iostream> #include <stdio.h> #include <queue> #include <stdio.h> #include <string.h> #include <vector> #include <queue> #include <set> #include <algorithm> #include <map> #include <stack> #include <math.h> #define Max(a,b) ((a)>(b)?(a):(b)) #define Min(a,b) ((a)<(b)?(a):(b)) using namespace std ; typedef long long LL ; const int M_P=1008 ; const LL Mod=1000000007 ; bool isprime[M_P+8] ; int prime[M_P] ,id; map<int ,int>my_hash ; map<int ,int>::iterator p ; void make_prime(){ id=0 ; memset(isprime,0,sizeof(isprime)) ; for(int i=2;i<=M_P;i++){ if(!isprime[i]) prime[++id]=i ; for(int j=1 ;j<=id&&i*prime[j]<=M_P;j++){ isprime[i*prime[j]]=1 ; if(i%prime[j]==0) break ; } } } LL C[258][258] ; void get_C(){ C[1][0]=C[1][1]=1 ; for(int i=2;i<=250;i++){ C[i][0]=C[i][i]=1 ; for(int j=1;j<i;j++){ C[i][j]=C[i-1][j-1]+C[i-1][j] ; if(C[i][j]>=Mod) C[i][j]%=Mod ; } } } void gao(int N){ for(int i=1;i<=id&&prime[i]*prime[i]<=N;i++){ if(N%prime[i]==0){ while(N%prime[i]==0){ my_hash[prime[i]]++ ; N/=prime[i] ; } } if(N==1) break ; } if(N!=1) my_hash[N]++ ; } vector<int>vec ; int N ; LL Sum(){ LL ans=1 ; for(int k=0;k<vec.size();k++){ ans*=C[vec[k]+N-1][N-1] ; if(ans>=Mod) ans%=Mod ; } for(int i=1;i<=N;i++){ LL sum=C[N][i] ; for(int k=0;k<vec.size();k++){ int m=N-i ; sum*=C[vec[k]+m-1][m-1] ; if(sum>=Mod) sum%=Mod ; } if(i&1) ans-=sum ; else ans+=sum ; ans=(ans%Mod+Mod)%Mod ; } return ans ; } int main(){ make_prime() ; get_C() ; int M ; while(scanf("%d",&N)!=EOF){ my_hash.clear() ; vec.clear() ; for(int i=1;i<=N;i++){ scanf("%d",&M) ; gao(M) ; } for(p=my_hash.begin();p!=my_hash.end();p++) vec.push_back(p->second) ; cout<<Sum()<<endl; } return 0 ; }