标签:style blog http color ar sp for div on
题目:http://codeforces.com/contest/396/problem/A
好久没做数论的东西了,一个获取素数的预处理跟素因子分解写错了,哭瞎了,呵呵,
首先ai最大值为10^9,n为500,最坏的情况 m最大值为500个10^9相乘,肯定不能获取m了,首选每一个ai肯定是m的一个因子,然后能分解就把ai给分解素因子,这样全部的ai都分解了 就能得到m的 所有素因子 以及 所有素因子的个数,题目求的 是n个因子的 不同序列的个数,所以每次 只能选出n个因子,这n个因子由素因子组成,其实就是对应每一个素因子 把它分配在n个位置上有多少种分法,然后所有素因子分法的 乘积就是最终的答案,至于怎么分配 其实就是隔板法
隔板法里有个是 允许有空的,这道题也是允许有空的
假设素因子p有 k个,那么分法就是 C[K + N - 1][N - 1],累积就可以了
const ll MOD = 1000000007;
int n;
map<int ,int > mp;
map<int ,int > ::iterator it;
const int MAXN = 15000;
int C[MAXN + 1][500 + 1];//m最大大概为x * 10^4500左右,所以大概需要2^15000
void Initial() {//组合数
int i,j;
for(i=0; i<=MAXN; i++) {
if(i <= 500)C[0][i] = 0ll;
C[i][0] = 1ll;
}
for(i=1; i<=MAXN; ++i) {
for(j=1; j<=MAXN && j <= 500; j++)
C[i][j] = (C[i-1][j] + C[i-1][j-1]) % MOD;
}
}
#define N 50009
int prime[N];
bool isprime[N];
int nprime = 0;
void make_prime() {//获取一定范围内素数
memset(isprime,false,sizeof(isprime));
for(int i=2;i<100005 ;i++)
if(!isprime[i])
for(int j=i*2;j<100005;j+=i)
isprime[j]=true;
for(int i=2;i<100005;i++)
if(!isprime[i])
prime[nprime++]=i;
}
void divide(int x) {//素因子分解
int temp = (int)sqrt(x * 1.0);
for(int i=0;i < nprime;i++) {
if(prime[i] > temp)break;
while(x%prime[i] == 0) {
mp[prime[i]]++;
x /= prime[i];
}
}
if(x != 1)mp[x]++;
}
void init() {
mp.clear();
}
bool input() {
while(scanf("%d",&n) == 1) {
return false;
}
return true;
}
void cal() {
for(int i=0;i<n;i++) {
int x;
scanf("%d",&x);
divide(x);
}
int ans = 1;
for(it = mp.begin();it != mp.end();it++) {
int tmp = it->second;
//int xx = C[tmp + n - 1][n - 1];
//int yy = C[1][0];
ans = (ans %MOD * C[tmp + n - 1][n - 1]%MOD)%MOD;
}
cout<<ans<<endl;
}
void output() {
}
int main() {
Initial();
make_prime();
while(true) {
init();
if(input())return 0;
cal();
output();
}
return 0;
}标签:style blog http color ar sp for div on
原文地址:http://blog.csdn.net/yitiaodacaidog/article/details/40868815