题解:将所有点的值按从小到大排序,考虑单点的最大值,最小值贡献,用并查集维护即可。
#include"bits/stdc++.h"
using namespace std;
typedef long long LL;
const int MAXN = 1e6+7;
struct node{
int id,val;
node(){}
node(int id, int val):id(id),val(val){}
bool operator < (const node &b) const{
return val < b.val;
}
}a[MAXN];
int n,f[MAXN],sz[MAXN];
vector<int> G[MAXN];
bool vis[MAXN];
LL ans;
int getfa(int x)
{
return f[x]==x? x : f[x]=getfa(f[x]);
}
void solve()
{
sort(a+1,a+1+n);
for(int i = 1; i <= n; i++) f[i] = i, sz[i] = 1, vis[i] = 0;
for(int i = 1; i <= n; i++){
int u = a[i].id;
vis[u] = 1;
for(int j = 0; j < G[u].size(); j++){
int v = G[u][j];
if(!vis[v]) continue;
int fv = getfa(v);
ans += (LL)sz[fv]*sz[u]*a[i].val;
sz[u] += sz[fv]; f[fv] = u;
}
}
}
int main()
{
scanf("%d",&n);
for(int i = 1; i <= n; i++){
scanf("%d",&a[i].val);
a[i].id = i;
}
for(int i = 1; i < n; i++){
int u,v;
scanf("%d%d",&u,&v);
G[u].push_back(v);
G[v].push_back(u);
}
solve();
for(int i = 1; i <= n; i++) a[i].val = -a[i].val;
solve();
cout<<ans<<endl;
return 0;
}