连通块计数
描述
题目描述:
小 A 有一棵长的很奇怪的树,他由 n 条链和 1 个点作为根构成,第 i条链有 ai 个点,每一条链的一端都与根结点相连。
现在小 A 想知道,这棵长得奇怪的树有多少非空的连通子树,你只需要输出答案对 998244353 取模的值即可
输入:
第一行一个正整数 n
第二行 n 个正整数 a1…an
1≤n≤10^5
1≤ai≤10^7
输出:
输出答案对998244353 取模后的值
样例输入
2
1 1
样例输出
6
包含中心的联通块数量 ∏(ai+1)--(1<=i<=n)
不包含中心的联通块数量∑(ai(ai+1)/2)--(1<=i<=n),也就是C(ai+1,2),每条链选择2条边截断
1 #include <cstdio> 2 #include <cstring> 3 #include <cmath> 4 #include<algorithm> 5 #include<iostream> 6 using namespace std; 7 typedef long long ll; 8 const ll mo=998244353; 9 const int maxn=1e7+5; 10 int n; 11 ll a[100005],ans=0; 12 ll fun[maxn]; 13 ll kpow(ll a,ll b) 14 { 15 ll res=1; 16 while(b>0) 17 { 18 if(b&1) res=res*a%mo,b--; 19 a=a*a%mo; 20 b/=2; 21 } 22 return res%mo; 23 } 24 ll C(ll n,ll m) 25 { 26 if(n<m) return 0; 27 return fun[n]*kpow(fun[m]*fun[n-m]%mo,mo-2)%mo; 28 } 29 void init(){ 30 fun[0]=1; 31 for(int i=1;i<=maxn;i++) 32 fun[i]=fun[i-1]*i%mo; 33 } 34 int main() 35 { 36 init(); 37 cin>>n; 38 for(int i=0;i<n;i++){ 39 cin>>a[i]; 40 ans+=C(a[i]+1,2); 41 ans%=mo; 42 } 43 ll b=1; 44 for(int i=0;i<n;i++){ 45 b*=(a[i]+1); 46 b%=mo; 47 } 48 cout<<(ans+b)%mo<<endl; 49 return 0; 50 }