当前位置: 代码迷 >> 综合 >> CodeForces - 396A On Number of Decompositions into Multipliers (组合数学+思维)
  详细解决方案

CodeForces - 396A On Number of Decompositions into Multipliers (组合数学+思维)

热度:57   发布时间:2023-11-15 15:39:46.0

题目大意:https://cn.vjudge.net/problem/CodeForces-396A

#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;
}

 

  相关解决方案