[ARC106] F - Figures
题面
题目描述
给定 \(n\) 个部件,每个部件有 \(a_i\) 个孔。现有 \(n-1\) 个连接件,要把 \(n\) 个部件连成一个连通块,问有多少种连接不同的方式。部件可以被区分,孔也可以被区分,连接件无法区分。对 \(998244353\) 取模。
数据范围
-
\(1\leq n\leq 10^5\)。
-
\(0\leq a_i \lt 998244353\)。
题解
首先根据 Prufer 序列的结论,可以得出题目要求的即为:
\[\displaystyle \sum_{\sum d_i=2n-2} \frac{(n-2)!}{\prod(d_i-1)!}\prod \frac{a_i!}{(a_i-d_i)!}
\]
\[=\displaystyle (n-2)! \sum_{\sum d_i=2n-2} \prod \frac{a_i!}{(d_i-1)!(a_i-d_i)!}
\]
\[=\displaystyle (n-2)! \sum_{\sum d_i=2n-2} \prod a_i\binom{a_i-1}{d_i-1}
\]
\[=\displaystyle (n-2)! \prod a_i \sum_{\sum d_i=2n-2} \prod\binom{a_i-1}{d_i-1}
\]
后面的组合数可以看成多元范德蒙德卷积,于是变为:
\[\displaystyle (n-2)!\prod a_i\cdot \binom{-n+\sum a_i}{n-2}
\]
\[=\displaystyle (-n+\sum a_i)^{\underline{n-2}} \prod a_i
\]
暴力计算下降幂即可,时间复杂度 \(O(n)\)。
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
using ll=long long;
const int N=2e5+9;
const int mod=998244353;
int a[N],n;
int FallPow(ll n,ll m){
if(m>n||m<0) return 0;
int res=1;
for(int i=1;i<=m;i++) res=1ll*res*((n-i+1)%mod)%mod;
return res;
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
ll sum=0,prod=1;
for(int i=1;i<=n;i++){
sum+=a[i];
prod=1ll*prod*a[i]%mod;
}
cout<<prod*FallPow(sum-n,n-2)%mod<<endl;
return 0;
}

浙公网安备 33010602011771号