0
1
mirror of https://git.sb/baoshuo/OI-codes.git synced 2024-12-24 18:31:59 +00:00

F - Imbalance Value of a Tree

https://codeforces.com/contest/915/submission/188221976
This commit is contained in:
Baoshuo Ren 2023-01-06 22:01:46 +08:00
parent 3ac636134e
commit 73fbb2f131
Signed by: baoshuo
GPG Key ID: 00CB9680AB29F51A

89
Codeforces/915/F/F.cpp Normal file
View File

@ -0,0 +1,89 @@
#include <iostream>
#include <algorithm>
#include <iterator>
#include <numeric>
#include <tuple>
#include <utility>
using std::cin;
using std::cout;
const char endl = '\n';
const int N = 1e6 + 5;
int n, a[N], fa_min[N], fa_max[N], siz_min[N], siz_max[N];
long long ans;
std::pair<int, int> e[N];
std::tuple<int, int, int> edges_min[N], edges_max[N];
int find(int *fa, int x) {
return fa[x] == x ? x : fa[x] = find(fa, fa[x]);
}
int main() {
std::ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
for (int i = 1; i < n; i++) {
cin >> e[i].first >> e[i].second;
}
std::fill(std::begin(siz_min), std::end(siz_min), 1);
std::fill(std::begin(siz_max), std::end(siz_max), 1);
std::iota(fa_min, fa_min + N, 0);
std::iota(fa_max, fa_max + N, 0);
std::transform(e + 1, e + n, edges_min + 1, [&](const std::pair<int, int> &edge) -> std::tuple<int, int, int> {
return std::make_tuple(edge.first, edge.second, std::min(a[edge.first], a[edge.second]));
});
std::transform(e + 1, e + n, edges_max + 1, [&](const std::pair<int, int> &edge) -> std::tuple<int, int, int> {
return std::make_tuple(edge.first, edge.second, std::max(a[edge.first], a[edge.second]));
});
std::sort(edges_min + 1, edges_min + n, [&](const std::tuple<int, int, int> &a, const std::tuple<int, int, int> &b) {
return std::get<2>(a) > std::get<2>(b);
});
std::sort(edges_max + 1, edges_max + n, [&](const std::tuple<int, int, int> &a, const std::tuple<int, int, int> &b) {
return std::get<2>(a) < std::get<2>(b);
});
cout << std::accumulate(edges_max + 1, edges_max + n, 0ll, [&](long long acc, const std::tuple<int, int, int> &cur) -> long long {
int u, v, w;
std::tie(u, v, w) = cur;
u = find(fa_max, u), v = find(fa_max, v);
if (u != v) {
acc += static_cast<long long>(w) * siz_max[u] * siz_max[v];
fa_max[u] = v;
siz_max[v] += siz_max[u];
}
return acc;
}) - std::accumulate(edges_min + 1, edges_min + n, 0ll, [&](long long acc, const std::tuple<int, int, int> &cur) -> long long {
int u, v, w;
std::tie(u, v, w) = cur;
u = find(fa_min, u), v = find(fa_min, v);
if (u != v) {
acc += static_cast<long long>(w) * siz_min[u] * siz_min[v];
fa_min[u] = v;
siz_min[v] += siz_min[u];
}
return acc;
})
<< endl;
return 0;
}