abc425E || Count Sequences 2
赛时脑子没转弯所以写了一个很唐的做法,挂上来图一乐。
思路
不考虑模数的话,是一道很典的组合数学。我们先假设每个数都不同,令
但模数不保证是质数,我们不能直接求逆元,所以我们应该用什么方式来避免掉除这一操作。发现
不过这个思路就图一乐吧,因为确实不优而且复杂度挺危险,建议学习其它题解的做法。
代码
#include<queue>
#include<vector>
#include<iostream>
#define int long long
using namespace std;
const int N=5005;
int t,n,ans,mod,sum,Max,qzh[N],A[N],cnt[N];
vector<pair<int,int> > num[N];
int qmi(int x,int y,int an=1){
while(y){
if(y&1) an=an*x%mod;
x=x*x%mod,y>>=1;
}
return an;
}
void solve(){
cin>>n;sum=Max=0,ans=1;
for(int i=1;i<=n;i++){
cin>>A[i];sum+=A[i];Max=max(Max,A[i]);
qzh[A[i]]++;
}
int s=0;
for(int i=Max;i>=1;i--){
s+=qzh[i];
for(auto a:num[i]) cnt[a.first]-=s*a.second;
}
for(int i=1;i<=sum;i++)
for(auto a:num[i]) cnt[a.first]+=a.second;
for(int i=1;i<=sum;i++){
if(cnt[i]) ans=ans*qmi(i,cnt[i])%mod;
cnt[i]=qzh[i]=0;
}
cout<<ans<<"\n";
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin>>t>>mod;
for(int i=2;i<=5000;i++){
int x=i;
for(int j=2;j*j<=x;j++){
int c=0;
while(x%j==0){c++;x/=j;}
if(c) num[i].push_back({j,c});
}
if(x!=1) num[i].push_back({x,1});
}
while(t--) solve();
return 0;
}