zoukankan      html  css  js  c++  java
  • [Codeforces915F] Imbalance Value of a Tree

    给定一棵 (n) 个点的无根树,每个点有点权 (a_i),求路径极差和。

    (n leq 10^6)

    每个点作为最大值和最小值分别算贡献。

    以最大值为例,按点权从小到大排序,每次加点把与这个点和已有点之间的边加上,用并查集维护子树大小,加边时候计数即可。

    这样每条边最多被访问两次。

    不过还可以优化,因为一条边一定在大的那一端的点加入时被加入,所以把边定一个边权等于 (max(a_x,a_y)),然后从小到大加边即可。

    我写的是加点的。

    #include <bits/stdc++.h>
    #define dbg(...) std::cerr << "33[32;1m", fprintf(stderr, __VA_ARGS__), std::cerr << "33[0m";
    template <class T, class U>
    inline bool smin(T &x, const U &y) { return y < x ? x = y, 1 : 0; }
    template <class T, class U>
    inline bool smax(T &x, const U &y) { return x < y ? x = y, 1 : 0; }
    
    using LL = long long;
    using PII = std::pair<int, int>;
    
    constexpr int N(1e6 + 5);
    int n, a[N], p[N], id[N];
    std::vector<int> g[N];
    
    int fa[N], siz[N];
    inline int find(int x) {
      while (fa[x] != x) x = fa[x] = fa[fa[x]];
      return x;
    }
    LL ans;
    void solve() {
      std::iota(p + 1, p + 1 + n, 1);
      std::iota(fa + 1, fa + 1 + n, 1);
      std::fill(siz + 1, siz + 1 + n, 1);
      std::sort(p + 1, p + 1 + n, [](int i, int j) { return a[i] < a[j]; });
      for (int i = 1; i <= n; i++) id[p[i]] = i;
      for (int i = 1; i <= n; i++) {
        int x = p[i], v = a[x];
        for (int y : g[x]) {
          if (id[y] > i) continue;
          x = find(x), y = find(y);
          ans += 1LL * siz[x] * siz[y] * v;
          if (siz[x] > siz[y]) std::swap(x, y);
          siz[y] += siz[x], fa[x] = y;
        }
      }
    }
    int main() {
      std::ios::sync_with_stdio(false);
      std::cin.tie(nullptr);
      std::cin >> n;
      for (int i = 1; i <= n; i++) std::cin >> a[i];
      for (int i = 1, x, y; i < n; i++) {
        std::cin >> x >> y;
        g[x].push_back(y), g[y].push_back(x);
      }
      solve();
      for (int i = 1; i <= n; i++) a[i] = -a[i];
      solve();
      std::cout << ans;
      return 0;
    }
    
  • 相关阅读:
    MFC单文档框架分析及执行流程(转)
    MFC不同工程(解决方案)之间对话框资源的复制与重用方法(转)
    【DLL】动态库的创建,隐式加载和显式加载(转)
    H264协议(转)
    YUV颜色编码解析(转)
    windows下常用快捷键(转)
    【Sqlite3】SQLITE3使用总结(转)
    C++11 自动释放锁(转)
    alt+ F8 设置无效(转)
    Invalidate()(转)
  • 原文地址:https://www.cnblogs.com/HolyK/p/14237955.html
Copyright © 2011-2022 走看看