답안 #221610

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
221610 2020-04-10T14:14:28 Z rama_pang CEOI16_icc (CEOI16_icc) C++14
90 / 100
164 ms 632 KB
#include "icc.h"
#include <bits/stdc++.h>
using namespace std;

mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count());
vector<vector<int>> components;

int Query(vector<int> A, vector<int> B) {
  if (A.empty() || B.empty()) return 0;
  return query(A.size(), B.size(), A.data(), B.data());
}

int QueryComponent(vector<int> A, vector<int> B) {
  vector<int> P, Q;
  for (auto i : A) {
    for (auto j : components[i]) {
      P.emplace_back(j);
    }
  }
  for (auto i : B) {
    for (auto j : components[i]) {
      Q.emplace_back(j);
    }
  }
  return Query(P, Q);
}

void Answer(int A, int B) {
  return setRoad(A, B);
}

int Split(int L, int R, vector<int> &A, vector<int> &B, int depth, bool Check) {
  if (depth == 0) {
    int mid = (L + R) / 2;
    for (int i = L; i <= mid; i++) A.emplace_back(i);
    for (int i = mid + 1; i <= R; i++) B.emplace_back(i);
    return max(mid - L + 1, R - mid);
  }
  int mid = (L + R) / 2;
  if (Check) {
    return max(Split(L, mid, A, B, depth - 1, Check), Split(mid + 1, R, A, B, depth - 1, Check));
  } else {
    vector<int> tA, tB;
    Split(L, mid, tA, tB, depth - 1, true);
    if (QueryComponent(tA, tB)) {
      return Split(L, mid, A, B, depth - 1, Check);
    } else {
      return Split(mid + 1, R, A, B, depth - 1, Check);
    }
  }
}

pair<int, int> BinarySearch(vector<int> A, vector<int> B, bool onComponent) {
  if (A.size() < B.size()) swap(A, B);
  if (A.size() == 1 && B.size() == 1) return {A[0], B[0]};

  int mid = A.size() / 2;
  vector<int> L(begin(A), begin(A) + mid), R(begin(A) + mid, end(A));

  bool res;
  if (onComponent) {
    if (R.empty() || QueryComponent(L, B)) {
      return BinarySearch(L, B, onComponent);
    } else {
      return BinarySearch(R, B, onComponent);
    }
  } else {
    if (R.empty() || Query(L, B)) {
      return BinarySearch(L, B, onComponent);
    } else {
      return BinarySearch(R, B, onComponent);
    }
  }
}

void MergeComponent(int C1, int C2) {
  vector<int> Merged;
  for (auto i : components[C1]) Merged.emplace_back(i);
  for (auto i : components[C2]) Merged.emplace_back(i);
  components[C1].clear();
  components[C2].clear();
  sort(begin(components), end(components), [&](const vector<int> &a, const vector<int> &b) {
    return a.size() > b.size();
  });

  while (components.back().empty()) components.pop_back();
  components.emplace_back(Merged);
}

void run(int N) {
  for (int i = 1; i <= N; i++) {
    components.emplace_back(vector<int>{i});
  }

  for (int i = 1; i < N; i++) {
    shuffle(begin(components), end(components), rnd);
    vector<int> A, B; // find two components that are connected by new edge
    for (int depth = 0; ; depth++) {
      int sz = Split(0, components.size() - 1, A, B, depth, true);
      if (sz == 1) break;
      int res = QueryComponent(A, B);
      A.clear(), B.clear();
      if (res) {
        Split(0, components.size() - 1, A, B, depth, false);
        break;
      }
    }

    // Binary Search to find edge's endpoint
    auto TwoComp = BinarySearch(A, B, true);
    auto Edge = BinarySearch(components[TwoComp.first], components[TwoComp.second], false);
    Answer(Edge.first, Edge.second);
    MergeComponent(TwoComp.first, TwoComp.second);
  }
}

Compilation message

icc.cpp: In function 'std::pair<int, int> BinarySearch(std::vector<int>, std::vector<int>, bool)':
icc.cpp:60:8: warning: unused variable 'res' [-Wunused-variable]
   bool res;
        ^~~
# 결과 실행 시간 메모리 Grader output
1 Correct 11 ms 512 KB Ok! 111 queries used.
2 Correct 12 ms 512 KB Ok! 109 queries used.
# 결과 실행 시간 메모리 Grader output
1 Correct 55 ms 512 KB Ok! 625 queries used.
2 Correct 47 ms 512 KB Ok! 621 queries used.
3 Correct 48 ms 512 KB Ok! 631 queries used.
# 결과 실행 시간 메모리 Grader output
1 Correct 144 ms 512 KB Ok! 1544 queries used.
2 Correct 153 ms 632 KB Ok! 1556 queries used.
3 Correct 155 ms 512 KB Ok! 1647 queries used.
4 Correct 153 ms 600 KB Ok! 1545 queries used.
# 결과 실행 시간 메모리 Grader output
1 Correct 164 ms 608 KB Ok! 1662 queries used.
2 Correct 147 ms 512 KB Ok! 1596 queries used.
3 Correct 150 ms 512 KB Ok! 1672 queries used.
4 Correct 146 ms 576 KB Ok! 1562 queries used.
# 결과 실행 시간 메모리 Grader output
1 Correct 164 ms 632 KB Ok! 1655 queries used.
2 Correct 155 ms 608 KB Ok! 1668 queries used.
3 Correct 149 ms 512 KB Ok! 1619 queries used.
4 Correct 150 ms 632 KB Ok! 1615 queries used.
5 Correct 152 ms 632 KB Ok! 1551 queries used.
6 Correct 138 ms 564 KB Ok! 1457 queries used.
# 결과 실행 시간 메모리 Grader output
1 Incorrect 152 ms 512 KB Too many queries! 1657 out of 1625
2 Halted 0 ms 0 KB -