Number Sequence
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 a 1a 2…a n=b 1b 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 1b 2*…*b n<=10 25).
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
题意
给出b1∗b2∗⋯∗bnb_1*b_2*\cdots*b_nb1∗b2∗⋯∗bn求能使a1∗a2∗⋯∗an=b1∗b2∗⋯∗bna_1*a_2*\cdots*a_n=b_1*b_2*\cdots*b_na1∗a2∗⋯∗an=b1∗b2∗⋯∗bn的长度为n的an的an的a数组的个数,其中ai>1a_i>1ai>1
题解
分出每个bib_ibi的素因子(与素因子大小无关),将m个相同的素因子放在nnn个位置,就是Cn+m−1n−1C_{n+m-1}^{n-1}Cn+m−1n−1。然后将每个不同的素因子都计算一遍。
但是很明显题中要求ai>1a_i>1ai>1,所以位置不能为空,而我们求的是存在空位置的。因此通过容斥,得ans=无空位计算值−空一位计算值+空两位计算值−⋯ans=无空位计算值-空一位计算值+空两位计算值-\cdotsans=无空位计算值−空一位计算值+空两位计算值−⋯
代码
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <queue>
#include <cmath>
#include <string>
#include <cstring>
#include <map>
#include <set>
#include <cmath>
using namespace std;
#define me(x,y) memset(x,y,sizeof x)
#define MIN(x,y) x < y ? x : y
#define MAX(x,y) x > y ? x : y
typedef long long ll;
const int maxn = 1e6;
const double INF = 0x3f3f3f3f;
const int MOD = 1e9+7;
int comb[110][110];
void C(){
for(int i = 0; i <= 50; ++i){
comb[i][0] = comb[i][i] = 1;
for(int j = 1; j < i; ++j){
comb[i][j] = comb[i-1][j]+comb[i-1][j-1];
comb[i][j] %= MOD;
}
}
}
int main(){
int n;
int b[22];
C();
while(cin>>n){
for(int i = 1; i <= n; ++i) scanf("%d",&b[i]);
vector<int>v;
vector<int>vv;
for(int i = 1; i <= n; ++i){
int x=b[i];
for(int j = 2; j*j <= x; ++j){
while(x%j == 0){
v.push_back(j);
x /= j;
}
}
if(x > 1) v.push_back(x);
}
sort(v.begin(),v.end());
vv.push_back(1);
for(int i = 1; i < v.size(); ++i){
if(v[i]!=v[i-1]) vv.push_back(1);
else vv[vv.size()-1]++;
}
ll sum = 0;
for(int i = 0; i < n; ++i){
ll ans = comb[n][i];
for(int j = 0;j < vv.size();++j){
ans = (ans*comb[vv[j]+n-i-1][n-i-1])%MOD;
}
if(i&1) sum = ((sum-ans)%MOD+MOD)%MOD;
else sum = (sum+ans)%MOD;
}
cout<<sum<<endl;
}
return 0;
}
/*
*/
博客围绕数字序列问题展开,给定序列b1,b2…bn,求满足a1a2…an=b1b2*…bn(ai>1)的序列a1,a2,…,an的个数。介绍了输入输出格式及样例,题解是先分出bi素因子,用组合数计算,再通过容斥原理处理空位问题。
&spm=1001.2101.3001.5002&articleId=89949713&d=1&t=3&u=10a3f2ac0528430f979e8d7d408ba41e)
886

被折叠的 条评论
为什么被折叠?



