题目大意
有n个点集,第i个点集的大小为ai,所有点互不相同,一条边连接两个点集中的某一对点,求以点集为单位的生成树个数同时满足每个点只被连最多一次
2<=n<=2e5
题解
直接爬
考虑prufer序上计数,一个度数为x的数的出现次数为x-1,数i的度数为j的方案为A(ai,j)
(prod_isum_{j>=0} frac{x^j}{j!} A_{ai}^{j+1}=prod_i ai(x+1)^{ai-1})
乘起来算即可
code
#include <bits/stdc++.h>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define mod 998244353
#define Mod 998244351
#define ll long long
//#define file
using namespace std;
int a[200001],n,i,j,k,l;
ll ans,sum;
ll qpower(ll a,int b) {ll ans=1; while (b) {if (b&1) ans=ans*a%mod;a=a*a%mod;b>>=1;} return ans;}
ll C(ll n,int m)
{
ll s1=1,s2=1,i;
fd(i,n,n-m+1) s1=s1*(i%mod)%mod;
fo(i,1,m) s2=s2*i%mod;
return s1*qpower(s2,Mod)%mod;
}
int main()
{
#ifdef file
freopen("f.in","r",stdin);
#endif
scanf("%d",&n),ans=1;
fo(i,1,n) scanf("%d",&a[i]),sum+=a[i]-1,ans=ans*a[i]%mod;
ans=ans*C(sum,n-2)%mod;
fo(i,1,n-2) ans=ans*i%mod;
printf("%lld
",ans);
fclose(stdin);
fclose(stdout);
return 0;
}