library

This documentation is automatically generated by online-judge-tools/verification-helper

View the Project on GitHub maspypy/library

:warning: graph/blackbox/interval_graph_unionfind.hpp

Depends on

Code

#include "ds/unionfind/unionfind.hpp"

// 区間は [L, R). 交わりが空でないものを union.
// https://codeforces.com/contest/1209/problem/G1
UnionFind interval_graph_unionfind(int N, vc<int> L, vc<int> R) {
  // 包含のある場合含まれているものをマージして削除する
  // 包含がなくなったら隣接しているものをマージする
  assert(len(L) == N && len(R) == N);
  vc<int> I(N);
  FOR(i, N) I[i] = i;

  sort(all(I), [&](auto& a, auto& b) -> bool {
    if (L[a] != L[b]) return L[a] < L[b];
    return R[a] > R[b];
  });

  UnionFind uf(N);
  vc<int> keep;
  for (auto& j: I) {
    if (!keep.empty()) {
      int i = keep.back();
      if (R[j] <= R[i] && R[j] - L[j] < R[i] - L[i]) {
        uf.merge(i, j);
        continue;
      }
    }
    keep.eb(j);
  }
  FOR(k, len(keep) - 1) {
    int i = keep[k], j = keep[k + 1];
    if (max(L[i], L[j]) < min(R[i], R[j])) uf.merge(i, j);
  }
  return uf;
}
#line 1 "graph/blackbox/interval_graph_unionfind.hpp"

#line 2 "ds/unionfind/unionfind.hpp"

struct UnionFind {
  int n, n_comp;
  vc<int> dat; // par or (-size)
  UnionFind(int n = 0) { build(n); }

  void build(int m) {
    n = m, n_comp = m;
    dat.assign(n, -1);
  }

  void reset() { build(n); }

  int operator[](int x) {
    while (dat[x] >= 0) {
      int pp = dat[dat[x]];
      if (pp < 0) { return dat[x]; }
      x = dat[x] = pp;
    }
    return x;
  }

  ll size(int x) {
    x = (*this)[x];
    return -dat[x];
  }

  bool merge(int x, int y) {
    x = (*this)[x], y = (*this)[y];
    if (x == y) return false;
    if (-dat[x] < -dat[y]) swap(x, y);
    dat[x] += dat[y], dat[y] = x, n_comp--;
    return true;
  }

  vc<int> get_all() {
    vc<int> A(n);
    FOR(i, n) A[i] = (*this)[i];
    return A;
  }
};
#line 3 "graph/blackbox/interval_graph_unionfind.hpp"

// 区間は [L, R). 交わりが空でないものを union.
// https://codeforces.com/contest/1209/problem/G1
UnionFind interval_graph_unionfind(int N, vc<int> L, vc<int> R) {
  // 包含のある場合含まれているものをマージして削除する
  // 包含がなくなったら隣接しているものをマージする
  assert(len(L) == N && len(R) == N);
  vc<int> I(N);
  FOR(i, N) I[i] = i;

  sort(all(I), [&](auto& a, auto& b) -> bool {
    if (L[a] != L[b]) return L[a] < L[b];
    return R[a] > R[b];
  });

  UnionFind uf(N);
  vc<int> keep;
  for (auto& j: I) {
    if (!keep.empty()) {
      int i = keep.back();
      if (R[j] <= R[i] && R[j] - L[j] < R[i] - L[i]) {
        uf.merge(i, j);
        continue;
      }
    }
    keep.eb(j);
  }
  FOR(k, len(keep) - 1) {
    int i = keep[k], j = keep[k + 1];
    if (max(L[i], L[j]) < min(R[i], R[j])) uf.merge(i, j);
  }
  return uf;
}
Back to top page