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;
}