제출 #1142183

#제출 시각아이디문제언어결과실행 시간메모리
1142183LucaLucaMPort Facility (JOI17_port_facility)C++17
0 / 100
21 ms47168 KiB
#include <iostream>
#include <vector>
#include <algorithm>
#include <cassert>
// acm doar trb sa dau lock in si sa bag jmenu lui voicu
// daca e raspunsu 0 e jover :sob: :pray:
using ll = long long;
#define debug(x) #x << " = " << x << '\n'

const int NMAX = 1e6;
const int mod = 1e9 + 7;

std::vector<int> sweep[2 * NMAX + 1];

struct Container {
  int x, y;
  bool operator < (const Container &other) const {
    return x != other.x? x < other.x : y < other.y;
  };
};

Container a[NMAX + 1];

namespace DSU {
  std::vector<int> p;
  std::vector<int> color;

  void init(int n) {
    p.resize(n + 1);
    color.resize(n + 1, 0);
    for (int i = 1; i <= n; i++) {
      p[i] = i;
      color[i] = 0;
    }
  }

  int root(int u) {
    return p[u] == u? u : p[u] = root(p[u]);
  }
  bool join(int u, int v) {
    u = root(u);
    v = root(v);
    if (u != v) {
      p[u] = v;
    } else {
      if (color[u] == color[v]) {
        return false;
      }
    }
    return true;
  }
};

int main() {
  #ifdef LOCAL
    freopen("input.txt", "r", stdin);
  #endif
  std::ios_base::sync_with_stdio(false);
  std::cin.tie(0);

  int n;
  std::cin >> n;

  for (int i = 1; i <= n; i++) {
    std::cin >> a[i].x >> a[i].y;
  }

  std::sort(a + 1, a + n + 1);
  for (int i = 1; i <= n; i++) {
    sweep[a[i].x].push_back(i);
  }

  if (n <= 2000) {
    DSU::init(n);
    for (int i = 1; i < n; i++) {
      for (int j = i + 1; j <= n; j++) {
        if (a[i].y > a[j].x && a[i].y < a[j].y) {
          if (!(DSU::join(i, j))) {
            std::cout << 0;
            return 0;
          }
        }
      }
    }
  }
  DSU::init(n);

  std::vector<int> maxR(2 * n + 1, -1);
  std::vector<int> who(2 * n + 1, -1);

  auto activate = [&](int index) {
    maxR[a[index].x] = a[index].y;
    who[a[index].x] = index;
  };
  auto deactivate = [&](int index) {
    maxR[a[index].x] = -1;
    who[a[index].x] = -1;
  };
  auto query = [&](int l, int r) {
    int maxi = -1, index = -1;
    for (int i = l; i <= r; i++) { 
      if (maxR[i] > maxi) {
        maxi = maxR[i];
        index = who[i];
      }
    }
    return index;
  };

  DSU::init(n);

  int answer = 1;
  for (int L = 2 * n; L > 0; L--) {
    for (const auto &index : sweep[L]) {
      auto [x, y] = a[index];
      int other = query(x, y);
      while (other != -1 && y < a[other].y) {
        // std::cout << "JOIN: " << index << ' ' << other << '\n';
        if (!DSU::join(index, other)) {
          answer = 0;
          break;
        }
        deactivate(other);
        other = query(x, y);
      } 
      activate(index);
    }
  }

  if (answer != 0) {
    for (int i = 1; i <= n; i++) {
      if (DSU::root(i) == i) {
        answer = 2 * answer % mod;
      }
    }
  }
  
  std::cout << answer;

  return 0;
} 
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...