CF1151E Number of Components

喵喵题

由于 \(\sum\limits_{l=1}^n\sum\limits_{r=l}^nf(l,r)\) 难以求解,考虑转化,

连通块个数 \(=\) 点数 \(-\) 边数,

可以将所有的点数和所有的边数分开求和处理。

\(a_i\) 表示第 \(i\) 个数的权值,\(l_i\)\(r_i\) 表示第 \(i\) 条边两个端点的编号,

考虑点数:只有 $ l\le a_i $ 且 $r \ge a_i $ 时第 \(i\) 个数会被取到,取到次数为 \(a_i\times(n+1-a_i)\)

考虑边数:只有 $ l\le \min(a_{l_i},a_{r_i}) $ 且 $r \ge \max(a_{l_i},a_{r_i}) $ 时第 \(i\) 条边会被取到,取到次数为 \(\min(a_{l_i},a_{r_i}) \times (n-\max(a_{l_i},a_{r_i})+1)\)

最后将点数减去边数即为答案。

#include<bits/stdc++.h>
using namespace std;
int read()
{
	int x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9') f=(ch=='-')?-1:1,ch=getchar();
	while(ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
	return x*f;
}
int main()
{
	const int n=read(),n1=n+1;
	long long x,pre=read(),ans=pre*(n1-pre);
	for(int i=2;i<=n;i++) x=read(),ans+=x*(n1-x)-((x<pre)?x*(n1-pre):pre*(n1-x)),pre=x;
	printf("%lld\n",ans);
	return 0;
}
posted @ 2023-03-19 20:45  所见皆为虚妄  阅读(12)  评论(0编辑  收藏  举报