답안 #58586

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
58586 2018-07-18T10:29:41 Z ruhanhabib39 CEOI16_icc (CEOI16_icc) C++17
0 / 100
400 ms 780 KB
#include "icc.h"
#include <bits/stdc++.h>
using namespace std;

// query(|A|,|B|,A,B) (A, B) disjoint, returns whether there's an edge between A, B
// setRoad(u,v) tells there's an edge u--v

namespace {
   int par[100 + 10];
   vector<int> st[100 + 10];
   vector<int> sts;
   int N;
   void init(int N_) {
      N = N_; sts.reserve(N);
      for(int i = 1; i <= N; i++) {
         par[i] = i;
         st[i].push_back(i);
         sts.push_back(i);
      }
   }
   int find(int u) {
      if(par[u] == u) return u;
      return par[u] = find(par[u]);
   }
   void merge(int u, int v) {
      u = find(u); v = find(v);
      if(u == v) return;
      if(st[v].size() > st[u].size()) {
         swap(v, u);
      }
      par[v] = u;
      st[u].insert(st[u].end(), st[v].begin(), st[v].end());
      sort(st[u].begin(), st[u].end());
      st[u].resize(unique(st[u].begin(), st[u].end()) - st[u].begin());
      sts.erase(find(sts.begin(), sts.end(), v));
      cerr << "merge(" << u << ", " << v << ")\n";
   }
   vector<int> build(int l, int r) {
      vector<int> rs;
      for(int i = l; i <= r; i++) {
         rs.insert(rs.end(), st[sts[i]].begin(), st[sts[i]].end());
      }
      return rs;
   }
   vector<int> get(vector<int> v, int l, int r) {
      vector<int> rs(v.begin() + l, v.begin() + r + 1);
      return rs;
   }
   bool hasEdge(int al, int ar, int bl, int br) {
      auto A = build(al, ar); auto B = build(bl, br);
      bool rs = query(A.size(), B.size(), A.data(), B.data());
      return rs;
   }
   void superPinPoint(int u, int v) {
      //cerr << "superPinPoint(" << u << ", " << v << ")\n";
      auto A = st[u]; auto B = st[v];
      while(A.size() > 1) {
         //cerr << "|A| = " << A.size() << "\n";
         int m = (A.size() - 1)/ 2;
         //cerr << "m = " << m << "\n";
         auto AA = get(A, 0, m);
         //cerr << "|AA| = " << AA.size() << "\n";
         if(query(AA.size(), B.size(), AA.data(), B.data())) A = AA;
         else A = get(A, m+1, A.size()-1);
      }
      while(B.size() > 1) {
         int m = (B.size() - 1) / 2;
         auto BB = get(B, 0, m);
         if(query(A.size(), BB.size(), A.data(), BB.data())) B = BB;
         else B = get(B, m+1, B.size()-1);
      }
      setRoad(A[0], B[0]);
   }
   void pinpointEdge(int l0, int r0, int l1, int r1) {
      //cerr << "pinpointing\n";
      //cerr << "[" << l0 << ", " << r0 << "]\n";
      while(l0 < r0) {
         //cerr << "left[" << l0 << ", " << r0 << "]\n";
         int m = (l0 + r0) / 2;
         if(hasEdge(l0,m,l1,r1)) r0 = m;
         else l0 = m + 1;
      }
      while(l1 < r1) {
         int m = (l1 + r1) / 2;
         if(hasEdge(l0,r0,l1,m)) r1 = m;
         else l1 = m + 1;
      }
      int u = sts[l0], v = sts[l1];
      superPinPoint(u, v);
      merge(u, v);
   }
   bool findEdge(int l, int r) {
      if(l >= r) return false;
      int m = (l + r) / 2;
      if(hasEdge(l,m,m+1, r)) {
         pinpointEdge(l, m, m+1, r);
         return true;
      }
      return findEdge(l, m) or findEdge(m+1, r);
   }
};

void run(int n) {
   init(n);
   for(int i = 0; i < n-1; i++) {
      findEdge(0,sts.size()-1);
   }
}
# 결과 실행 시간 메모리 Grader output
1 Incorrect 14 ms 504 KB Program is not terminated properly.
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 70 ms 744 KB Program is not terminated properly.
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 400 ms 744 KB Program is not terminated properly.
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 338 ms 748 KB Program is not terminated properly.
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 304 ms 756 KB Program is not terminated properly.
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 347 ms 780 KB Program is not terminated properly.
2 Halted 0 ms 0 KB -