牛客國慶集訓派對Day4 I-連通塊計數(思維,組合數學)
阿新 • • 發佈:2018-12-14
時間限制:C/C++ 1秒,其他語言2秒 空間限制:C/C++ 1048576K,其他語言2097152K 64bit IO Format: %lld
題目描述
小 A 有一棵長的很奇怪的樹,他由 n 條鏈和 1 個點作為根構成,第 i 條鏈有 ai 個點,每一條鏈的一端都與根結點相連。 現在小 A 想知道,這棵長得奇怪的樹有多少非空的連通子樹,你只需要輸出答案對 998244353 取模的值即可
輸入描述:
第一行一個正整數 n 第二行 n 個正整數 a1…an
輸出描述:
輸出答案對 998244353 取模後的值
示例1
輸入
2 1 1
輸出
6
備註:
1≤ n≤ 10^5 1≤ ai≤ 10^7
思路
連通塊分成兩種:連通子樹的點在同一條鏈上和在多條鏈上;
- 連通子樹的點在一條鏈上:算上根節點,每條鏈上一共有a[i]+1個點,每條鏈上有個連通子樹,所以該情況的連通子樹共有個
- 連通子樹的點在多條鏈上:每條鏈上有選擇0,1,2,......a[i]這a[i]+1種選法,所以該情況一共有個連通子樹
然後把上述兩種情況的連通子樹數量相加即可
AC程式碼
/* * @Author: WZY * @Date: 2018-10-09 16:36:48 * @Last Modified by: WZY * @Last Modified time: 2018-10-09 17:28:52 */ #include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> #include <math.h> #include <limits.h> #include <map> #include <stack> #include <queue> #include <vector> #include <set> #include <string> #include <time.h> #define ll long long #define ull unsigned long long #define ms(a) memset(a,0,sizeof(a)) #define pi acos(-1.0) #define INF 0x7f7f7f7f #define lson o<<1 #define rson o<<1|1 #define debug(...) cerr<<"["<<#__VA_ARGS__":"<<(__VA_ARGS__)<<"]"<<"\n" const double E=exp(1); const int maxn=1e6+10; const int mod=998244353; using namespace std; ll a[maxn]; int main(int argc, char const *argv[]) { ios::sync_with_stdio(false); #ifndef ONLINE_JUDGE freopen("in.txt", "r", stdin); freopen("out.txt", "w", stdout); double _begin_time = clock(); #endif ll n; cin>>n; ll res=0; for(int i=0;i<n;i++) { cin>>a[i]; res=res+(a[i]+1)*a[i]/2%mod; } ll ans=1; for(int i=0;i<n;i++) ans=ans*(a[i]+1)%mod; cout<<(ans+res)%mod<<endl; #ifndef ONLINE_JUDGE long _end_time = clock(); printf("time = %lf ms.", _end_time - _begin_time); #endif return 0; }