396A On Number of Decompositions into Multipliers (組合數學+思維)
阿新 • • 發佈:2018-12-10
#include<bits/stdc++.h> using namespace std; #define debug puts("YES"); #define rep(x,y,z) for(int (x)=(y);(x)<(z);(x)++) #define read(x,y) scanf("%d%d",&x,&y) #define ll long long #define lrt int l,int r,int rt #define lson l,mid,rt<<1 #define rson mid+1,r,rt<<1|1 const int maxn =1e6+5; const int mod=1e9+7; ll powmod(ll x,ll y){ll t=1;for(;y;y>>=1,x=x*x%mod) if(y&1) t=t*x%mod;return t;} ll gcd(ll x,ll y){return y?gcd(y,x%y):x;} /* 題目大意:給定n個數位, 其目標是m,要求有多少種分解方式。 組合計數,首先把總目標數字質因分解, 根據唯一分解性定理, 可以知道每次隔板其計數情況不會重複, 假如目標值為p1^k1*p2^k2*p3^k3*... 相當於有m種不同的球,個數為k1,k2,...km, 放入k個框中有多少種不同的放法。 分別對每種球進行k隔板,進行計數, 答案就是C(k+k1-1,k)*...C(k+km-1,k)。 */ ///資料域 ll n,x; ll ans; map<ll,int> mp; map<ll,int>::iterator it; ///篩法篩素數 int prim[maxn],tot=0; int vis[maxn]; void sieve() { for(int i=2;i<maxn;i++) { if(vis[i]==0) prim[tot++]=i; for(int j=0;j<tot;j++) { if(1LL*i*prim[j]>=maxn) break; int k=i*prim[j]; vis[k]=1; if(i%prim[j]==0) break; } } } ///組合數階乘逆元 ll fac[maxn],inv[maxn]; void init() { fac[0]=1;for(int i=1;i<maxn;i++) fac[i]=fac[i-1]*i%mod; inv[maxn-1]=powmod(fac[maxn-1],mod-2); for(int i=maxn-2;i>=0;i--) inv[i]=inv[i+1]*(i+1)%mod; } ll C(ll n,ll m) { return fac[n]*inv[m]%mod*inv[n-m]%mod; } int main() { sieve(); init(); scanf("%lld",&n); for(int i=0;i<n;i++) { scanf("%lld",&x); int tx=x,M=0; ll ans=1; for(int i=0;prim[i]<=tx&&i<tot;i++) { while(x%prim[i]==0) { x/=prim[i]; mp[prim[i]]++;///計數陣列遞增 M++; } } if(x>1) mp[x]++; } ans=1; for(it=mp.begin();it!=mp.end();it++) { int tp=it->second; ans=ans*C(tp+n-1,tp)%mod; } printf("%lld\n",ans); return 0; }