zoukankan      html  css  js  c++  java
  • [HNOI2016]最小公倍数

    • 给定无向图 ((V,E)),每条边有两个边权 (a_i, b_i)
    • (q) 次操作,给出 (u_j, v_j, a_j, b_j),问是否存在 (u, v) 之间的路径使得两个边权的最大值分别是 (a_j, b_j)
    • (|V|, q leq 5 imes 10^4, |E| leq 10^5)

    类似[APIO2019]桥梁

    • (N = q + |E|),边和操作和在一起都按 (a) 从大到小排序。
    • 对于 (a_i geq max a_j) 的边 (i),和操作一起按照 (b_i) 从大到小排序,动态加边并查集维护联通块和联通块最大值。这部分复杂度是 (O(Nlog N))
    • 对于 (min{a_j} leq a_i leq max{a_j}) 的边 (i),每次询问暴力访问,如果满足 (a_i geq a_j, b_i geq b_j) 就加入并查集。这部分是 (O(N^2log N))

    分块处理,设块大小为 (S),第一部分不变,第二部分变为 (O(S^2 log S))

    总复杂度 (O(frac {N^2}Slog N + NSlog S))

    #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(5e4 + 5), M(1e5 + 5), S(600);
    struct Data {
      int id, x, y, a, b;
      bool operator<(const Data &r) const {
        return a < r.a || a == r.a && id < r.id;
      }
    } a[M << 1];
    int fa[N], siz[N], maxa[N], maxb[N], ta[N], tb[N], tc[N], td[N];
    int find(int x) {
      while (fa[x] != x) x = fa[x];
      return x;
    }
    int ans[M];
    int main() {
      std::ios::sync_with_stdio(false);
      std::cin.tie(nullptr);
      int n, m, q;
      std::cin >> n >> m;
      for (int i = 1; i <= m; i++) {
        std::cin >> a[i].x >> a[i].y >> a[i].a >> a[i].b;
      }
      std::cin >> q;
      for (int i = 1; i <= q; i++) {
        auto &[id, x, y, a, b] = ::a[i + m];
        id = i;
        std::cin >> x >> y >> a >> b;
      }
      m += q;
      std::sort(a + 1, a + 1 + m);
      for (int i = 1; i <= m; i += S) {
        while (i <= m && !a[i].id) i++;
        std::vector<int> b, c, d;
        for (int j = 1; j < i; j++) if (!a[j].id) b.push_back(j), assert(a[j].a <= a[i].a);
        auto cmp_b = [](int i, int j) { return a[i].b < a[j].b; };
        std::sort(b.begin(), b.end(), cmp_b);
        for (int j = 0; j < S && i + j <= m; j++) { 
          if (a[i + j].id) {
            d.push_back(i + j);
          } else {
            c.push_back(i + j);
          }
        }
        std::sort(d.begin(), d.end(), cmp_b);
        std::iota(fa, fa + n + 1, 0);
        std::fill(siz, siz + n + 1, 1);
        std::fill(maxa, maxa + n + 1, -1);
        std::fill(maxb, maxb + n + 1, -1);
        auto p = b.begin();
        for (int j : d) {
          for (; p != b.end() && a[*p].b <= a[j].b; p++) {
            int x = find(a[*p].x), y = find(a[*p].y);
            if (x != y) {
              if (siz[x] > siz[y]) std::swap(x, y);
              fa[x] = y, siz[y] += siz[x];
              smax(maxa[y], maxa[x]);
              smax(maxb[y], maxb[x]);
            }
            smax(maxa[y], a[*p].a);
            smax(maxb[y], a[*p].b);
          }
          std::vector<std::pair<int*, int>> v;
          auto rec = [&](int &x) { v.emplace_back(&x, x); };
          for (int k : c) {
            if (a[k].a <= a[j].a && a[k].b <= a[j].b) {
              int x = find(a[k].x), y = find(a[k].y);
              if (siz[x] > siz[y]) std::swap(x, y);
              rec(maxa[y]), rec(maxb[y]);
              if (x != y) {
                rec(fa[x]), rec(siz[y]);
                fa[x] = y, siz[y] += siz[x];
                smax(maxa[y], maxa[x]);
                smax(maxb[y], maxb[x]);
              }
              smax(maxa[y], a[k].a);
              smax(maxb[y], a[k].b);
            }
          }
          int x = find(a[j].x), y = find(a[j].y);
          assert(a[j].id);
          ans[a[j].id] = x == y && maxa[x] == a[j].a && maxb[x] == a[j].b;
          while (!v.empty()) {
            auto &[x, y] = v.back();
            *x = y;
            v.pop_back();
          }
        }
      }
      for (int i = 1; i <= q; i++) {
        std::cout << (ans[i] ? "Yes
    " : "No
    ");
      }
      return 0;
    }
    
    
  • 相关阅读:
    《AI for Game Developers》第七章 A*路径寻找算法 (二)(skiplow翻译)
    芯片科普学习笔记
    sprboot 配置logback 日志输出
    springboot+mybatis 配置双数据源(mysql,oracle,sqlserver,db2)
    vue 封装axios请求
    *arg参数
    pytest mac安装了pytest,但是输入pytest却提示命令不存在
    构建Java Web开发环境
    在CentOS上编译安装PostgreSQL
    在Ubuntu 14.04上使用Eclipse开发和调试PosgreSQL9.3.4
  • 原文地址:https://www.cnblogs.com/HolyK/p/14333035.html
Copyright © 2011-2022 走看看