E. Number of Components
方法一:考虑每个点的贡献,认为一个联通块里让编号最大的点产生贡献
那么,对于一个点 i i i,如果对答案产生贡献,一定要点 i i i 存在,而点 i + 1 i + 1 i+1 不存在。
#define IO ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr)
#pragma GCC optimize(2)
#include<iostream>
#include<algorithm>
using namespace std;
using ll=long long;
constexpr int N=100010;
ll a[N];
int n;
int main()
{
IO;
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
ll res=0;
for(int i=1;i<n;i++)
{
ll x=a[i],y=a[i+1];
if(x>y)
res+=1ll*(n-x+1)*(x-y);
else
res+=1ll*(y-x)*x;
}
res+=a[n]*(n-a[n]+1);
cout<<res<<'\n';
return 0;
}
方法二:连通块数量=点数-边数于是点数和边数分开统计
点在连通块中的情况,对于 ( i , i + 1 ) (i,i+1) (i,i+1)这条边要在连通块中必须要求 i , i + 1 i,i+1 i,i+1同时在于是直接计算即可
#define IO ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr)
#pragma GCC optimize(2)
#include<iostream>
#include<algorithm>
using namespace std;
using ll=long long;
constexpr int N=100010;
ll a[N];
int n;
int main()
{
IO;
cin>>n;ll res=0;
for(int i=1;i<=n;i++)
{
cin>>a[i];
res+=a[i]*(n-a[i]+1);
}
for(int i=1;i<n;i++)
{
ll x=a[i],y=a[i+1];
res-=min(x,y)*(n-max(x,y)+1);
}
cout<<res<<'\n';
return 0;
}