2018 Wannafly summer camp Day8--连通块计数

连通块计数

描述

题目描述:

小 A 有一棵长的很奇怪的树,他由 n 条链和 1 个点作为根构成,第 i条链有 ai 个点,每一条链的一端都与根结点相连。

现在小 A 想知道,这棵长得奇怪的树有多少非空的连通子树,你只需要输出答案对 998244353 取模的值即可

输入:

第一行一个正整数 n

第二行 n 个正整数 a1an

1n10^5

1ai10^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 }
View Code

 

 

posted @ 2018-08-13 22:05  Chasssser  阅读(308)  评论(0编辑  收藏  举报