CF1151E题解

CF1151E

感觉这种类型的题目都很套路啊,因此写一篇题解来总结一下。

思路

首先看到连通块就应该敏锐地发现:连通块个数 = 点数 - 边数。

因此我们直接考虑分别记录点数和边数对答案的贡献。

对于点数,当前点对答案产生贡献需要满足 \(l\le a_i\le r\),因此会被计算 \(a_i(n-a_i)+1\) 次。

对于边数,对于两个点 \(i\)\(i+1\) 连成的边,只有两个点都被算入答案,整条边才会被算入答案,因此会被计算 \(\min(a_i,a_{i+1}(n-\max(a_i,a_{i+1})+1))\) 次。

总时间复杂度为 \(O(n)\)

代码

#include<iostream>
using namespace std;
typedef long long ll;
ll n,a,last,res;
int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin>>n;
	for(int i=1;i<=n;i++,last=a)
	{
		cin>>a;
		res+=a*(n-a+1)-(i>1)*min(a,last)*(n-max(a,last)+1);
	}
	cout<<res;
	return 0;
}
posted @ 2023-07-24 08:12  week_end  阅读(8)  评论(0编辑  收藏  举报