From 73fbb2f131eef86f56ccf0fa2a509d47ceb92d98 Mon Sep 17 00:00:00 2001 From: Baoshuo Date: Fri, 6 Jan 2023 22:01:46 +0800 Subject: [PATCH] F - Imbalance Value of a Tree https://codeforces.com/contest/915/submission/188221976 --- Codeforces/915/F/F.cpp | 89 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 Codeforces/915/F/F.cpp diff --git a/Codeforces/915/F/F.cpp b/Codeforces/915/F/F.cpp new file mode 100644 index 00000000..1ca03362 --- /dev/null +++ b/Codeforces/915/F/F.cpp @@ -0,0 +1,89 @@ +#include +#include +#include +#include +#include +#include + +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 e[N]; +std::tuple 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 &edge) -> std::tuple { + 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 &edge) -> std::tuple { + 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 &a, const std::tuple &b) { + return std::get<2>(a) > std::get<2>(b); + }); + std::sort(edges_max + 1, edges_max + n, [&](const std::tuple &a, const std::tuple &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 &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(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 &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(w) * siz_min[u] * siz_min[v]; + fa_min[u] = v; + siz_min[v] += siz_min[u]; + } + + return acc; + }) + << endl; + + return 0; +}