【题解】CF1151E Number of Components

CF1151E 题解

【题目大意】

给定一个有 n n n 个顶点的链式图,编号 1 ∼ n 1\sim n 1n,且 i i i 号节点的权值为 a i a_i ai. 对所有 1 ⩽ i < n 1\leqslant i<n 1i<n,编号 i i i i + 1 i+1 i+1 的点之间连有一条边.

定义函数 f ( l , r ) ( l ⩽ r ) f(l,r)(l\leqslant r) f(l,r)(lr) 为删除权值范围不在 l l l r r r 之间的点(某端为消失点的边也消失)后新图的连通块数量.

∑ i = 1 n ∑ j = i n f ( i , j ) \sum_{i=1}^n\sum_{j=i}^nf(i,j) i=1nj=inf(i,j) 的值。

【分析】

注意到此题中的图为一条链,并且求连通块数量,不难想到利用“连通块数量 = 点数 - 边数” ( 1 ) ^{(1)} (1)将原式转化为分别求点数和与边数和之差。(值得注意的是,这个公式只有在森林或树的情况下才成立)我们分别考虑每个点对答案的贡献。根据题意可得,权值为 a i a_i ai 的点只有 l ⩽ a i l\leqslant a_i lai a i ⩽ r a_i\leqslant r air 时才会做出贡献,而隐藏条件 1 ⩽ l , r ⩽ n 1\leqslant l,r\leqslant n 1l,rn 可知,该点会做出 a i × ( n − a i + 1 ) a_i\times(n-a_i+1) ai×(nai+1) 次贡献。因此,点数之和为 ∑ i = 1 n a i ( n − a i + 1 ) \sum_{i=1}^na_i(n-a_i+1) i=1nai(nai+1)。边数之和也是如此,两端权值分别为 a i a_i ai a i + 1 a_{i+1} ai+1 的边做出贡献时需要满足 l ⩽ a i ⩽ r l\leqslant a_i\leqslant r lair l ⩽ a i + 1 ⩽ r l\leqslant a_{i+1}\leqslant r lai+1r,也就是 l ⩽ min ⁡ ( a i , a i + 1 ) l\leqslant\min(a_i,a_{i+1}) lmin(ai,ai+1) 以及 r ⩾ max ⁡ ( a i , a i + 1 ) r\geqslant \max(a_i,a_{i+1}) rmax(ai,ai+1),所以该边会被计算 min ⁡ ( a i , a i + 1 ) × ( n − max ⁡ ( a i , a i + 1 ) + 1 ) \min(a_i,a_{i+1})\times(n-\max(a_i,a_{i+1})+1) min(ai,ai+1)×(nmax(ai,ai+1)+1) 次。所以这题就做完了。

【代码】

#include <bits/stdc++.h>
#define int long long
using namespace std;
inline int read(){
	int s = 0, w = 1;
	char ch = getchar();
	for(; ch < '0' || ch > '9'; w *= ch == '-' ? -1 : 1, ch = getchar());
	for(; ch >= '0' && ch <= '9'; s = 10 * s + ch - '0', ch = getchar());
	return s * w;
}
const int MAXN = 100005;
int n, a[MAXN];
signed main(){
	n = read();
	for(int i = 1; i <= n; i++){
		a[i] = read();
	}
	int res = 0;
	for(int i = 1; i <= n; i++){
		res += a[i] * (n - a[i] + 1);
	}
	for(int i = 1; i < n; i++){
		res -= min(a[i], a[i + 1]) * (n - max(a[i], a[i + 1]) + 1);
	}
	cout << res << endl;
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值