连通块计数

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/westbrook1998/article/details/82939476

链接:https://www.nowcoder.com/acm/contest/204/I
来源:牛客网
题目描述
小 A 有一棵长的很奇怪的树,他由 n 条链和 1 个点作为根构成,第 i 条链有 ai 个点,每一条链的一端都与根结点相连。
现在小 A 想知道,这棵长得奇怪的树有多少非空的连通子树,你只需要输出答案对 998244353 取模的值即可
输入描述:
第一行一个正整数 n
第二行 n 个正整数 a1…an
输出描述:
输出答案对 998244353 取模后的值
示例1
输入
复制
2
1 1
输出
复制
6
备注:
1≤ n≤ 105
1≤ ai≤ 107

卡了很久
一开始从组合数的方向想,然后不行后我就打表找规律,也不行,队友最后推出来
连通块数就分为两种(这个开始就确定的),从根出发的每条链单独的就用一个等差数列求和,a[i]*(a[i]+1)/2,然后通过根节点与其他节点相连通的,就考虑任意一个连通块,每条链贡献出多少节点,可以从0到a[i],所以就是sum(a[i]+1)
然后注意开long long

代码:

#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N=1e5+50;
const int MOD=998244353;
ll a[N];
int n;
int main(void){
    scanf("%d",&n);
    ll sum=1;
    for(int i=1;i<=n;i++){
        scanf("%lld",&a[i]);
        sum=(sum*(a[i]+1))%MOD;
    }
    for(int i=1;i<=n;i++){
        sum=(sum+(a[i]*(a[i]+1))/2)%MOD;
    }
    printf("%lld\n",sum);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/westbrook1998/article/details/82939476