题解:AT_abc425_e [ABC425E] Count Sequences 2
Claire0918 · · 题解
题目即求可重集排列方案数,我们知道答案为
证明是考虑其中分子为不考虑重复数的排列数,分母为相同数字的排列数。
但是我们知道模意义下除法需要逆元,而
Code:
#include<bits/stdc++.h>
#define mem(a, v) memset(a, v, sizeof(a))
using namespace std;
const int maxn = 3e5 + 10, maxa = 5000;
int t, n, mod;
long long res;
int a[maxn], cnt[maxa + 10];
vector<pair<int, int> > d[maxa + 10];
int main(){
scanf("%d %d", &t, &mod);
for (int i = 2; i <= maxa; i++){
int now = i;
for (int j = 2; j * j <= i; j++){
if (!(now % j)){
int cnt = 0;
for (;!(now % j); now /= j, cnt++);
d[i].push_back(make_pair(j, cnt));
}
}
now > 1 && (d[i].push_back(make_pair(now, 1)), 1538);
}
while (t--){
scanf("%d", &n), a[n + 1] = 0, res = 1;
for (int i = 1; i <= n; i++){
scanf("%d", &a[i]), a[n + 1] += a[i];
}
for (int i = 2; i <= a[n + 1]; i++){
for (auto x: d[i]){
cnt[x.first] += x.second;
}
}
for (int i = 1; i <= n; i++){
for (int j = 2; j <= a[i]; j++){
for (auto x: d[j]){
cnt[x.first] -= x.second;
}
}
}
for (int i = 2; i <= maxa; i++){
for (;cnt[i]; res = res * i % mod, cnt[i]--);
}
printf("%lld\n", res);
}
return 0;
}