[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;
}
posted @ 2025-04-15 09:55  JoeyJiang  阅读(9)  评论(0)    收藏  举报