답안 #570327

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
570327 2022-05-29T08:37:24 Z 600Mihnea CEOI16_icc (CEOI16_icc) C++17
100 / 100
138 ms 652 KB
#include <bits/stdc++.h>
#include "icc.h"

using namespace std;

mt19937 rng((long long) (new char));

int get(vector<int> a, vector<int> b) {
  if (a.empty() || b.empty()) {
    return 0;
  }
  return query((int) a.size(), (int) b.size(), a.data(), b.data());
}

vector<int> operator + (vector<int> a, vector<int> b) {
  for (auto &x : b) {
    a.push_back(x);
  }
  return a;
}

const int N = 100 + 7;
int t[N];

int get_root(int a) {
  if (t[a] == a) {
    return a;
  } else {
    return t[a] = get_root(t[a]);
  }
}

void join(int a, int b) {
  t[get_root(a)] = get_root(b);
}

void run(int n) {
  for (int i = 1; i <= n; i++) {
    t[i] = i;
  }
  for (int step = 1; step <= n - 1; step++) {
    vector<vector<int>> comps;
    for (int i = 1; i <= n; i++) {
      if (get_root(i) == i) {
        vector<int> currentComp;
        for (int j = 1; j <= n; j++) {
          if (get_root(j) == i) {
            currentComp.push_back(j);
          }
        }
        comps.push_back(currentComp);
      }
    }

    assert((int) comps.size() == n - step + 1);
    assert((int) comps.size() >= 2);

    shuffle(comps.begin(), comps.end(), rng);
    for (auto &comp : comps) {
      shuffle(comp.begin(), comp.end(), rng);
    }

    int MaxValue = (int) comps.size() - 1, Xor = 0;

    for (int bit = 0; (1 << bit) <= MaxValue; bit++) {
      vector<int> have, have_nots;
      for (int i = 0; i < (int) comps.size(); i++) {
        if (i & (1 << bit)) {
          have = have + comps[i];
        } else {
          have_nots = have_nots + comps[i];
        }
      }
      if (get(have, have_nots) == 1) {
        Xor += (1 << bit);
      }
    }

    assert(Xor > 0);

    int id_a = 0, id_b = 0, the_bit = -1;

    for (int bit = 0; (1 << bit) <= MaxValue; bit++) {
      if (Xor & (1 << bit)) {
        the_bit = bit;
      }
    }

    id_a = (1 << the_bit);

    assert(the_bit != -1);


    for (int bit = 0; (1 << bit) <= MaxValue; bit++) {
      if (bit == the_bit) {
        continue;
      }
      if (Xor & (1 << bit)) {
        vector<int> first, second;
        for (int i = 0; i < (int) comps.size(); i++) {
          int la_bit = !!(i & (1 << bit)), la_the = !!(i & (1 << the_bit));
          if (la_bit == 1 && la_the == 1) {
            first = first + comps[i];
          }
          if (la_bit == 0 && la_the == 0) {
            second = second + comps[i];
          }
        }
        if (get(first, second)) {
          id_a += (1 << bit);
        } else {
          id_b += (1 << bit);
        }
      } else {
        vector<int> first, second;
        for (int i = 0; i < (int) comps.size(); i++) {
          int la_bit = !!(i & (1 << bit)), la_the = !!(i & (1 << the_bit));
          if (la_bit == 0 && la_the == 1) {
            first = first + comps[i];
          }
          if (la_bit == 0 && la_the == 0) {
            second = second + comps[i];
          }
        }
        if (!get(first, second)) {
          id_a += (1 << bit);
          id_b += (1 << bit);
        } else {

        }
      }
    }


    assert((id_a ^ id_b) == Xor);
    assert(0 <= id_a && id_a < (int) comps.size());
    assert(0 <= id_b && id_b < (int) comps.size());
    /**for (auto &foo : comps) {
      cout << " ---> ";
      for (auto &x : foo) {
        cout << x << " ";
      }
      cout << "\n";
    }
    cout << id_a << " and " << id_b << "\n";**/
 ///   cout << id_a << " and " << id_b << "\n";
  ///  cout << (int) comps[id_a].size() << " and " << (int) comps[id_b].size() << "\n";

    auto p1 = comps[id_a];
    auto p2 = comps[id_b];

 ///   cout << (int) p1.size() << " and " << (int) p2.size() << "\n";

    while ((int) p1.size() > 1 || (int) p2.size() > 1) {
      shuffle(p1.begin(), p1.end(), rng);
      shuffle(p2.begin(), p2.end(), rng);
      if ((int) p2.size() < (int) p1.size()) {
        swap(p1, p2);
      }
      assert((int) p1.size() <= (int) p2.size());
      vector<int> X(p2.begin(), p2.begin() + (int)p2.size() / 2), Y(p2.begin() + (int) p2.size() / 2, p2.end());
      assert((int) X.size() + (int) Y.size() == (int) p2.size());
      if (get(p1, X)) {
        p2 = X;
      } else {
        p2 = Y;
      }
    }
    assert((int) p1.size() == 1 && (int) p2.size() == 1);
    join(p1[0], p2[0]);
    setRoad(p1[0], p2[0]);
  }
}
# 결과 실행 시간 메모리 Grader output
1 Correct 8 ms 512 KB Ok! 116 queries used.
2 Correct 10 ms 468 KB Ok! 117 queries used.
# 결과 실행 시간 메모리 Grader output
1 Correct 44 ms 508 KB Ok! 646 queries used.
2 Correct 34 ms 508 KB Ok! 538 queries used.
3 Correct 36 ms 468 KB Ok! 609 queries used.
# 결과 실행 시간 메모리 Grader output
1 Correct 121 ms 536 KB Ok! 1592 queries used.
2 Correct 130 ms 536 KB Ok! 1297 queries used.
3 Correct 132 ms 652 KB Ok! 1607 queries used.
4 Correct 117 ms 468 KB Ok! 1581 queries used.
# 결과 실행 시간 메모리 Grader output
1 Correct 125 ms 536 KB Ok! 1583 queries used.
2 Correct 138 ms 532 KB Ok! 1595 queries used.
3 Correct 121 ms 540 KB Ok! 1568 queries used.
4 Correct 119 ms 532 KB Ok! 1605 queries used.
# 결과 실행 시간 메모리 Grader output
1 Correct 121 ms 536 KB Ok! 1542 queries used.
2 Correct 116 ms 468 KB Ok! 1549 queries used.
3 Correct 118 ms 536 KB Ok! 1481 queries used.
4 Correct 118 ms 596 KB Ok! 1553 queries used.
5 Correct 125 ms 532 KB Ok! 1596 queries used.
6 Correct 122 ms 536 KB Ok! 1553 queries used.
# 결과 실행 시간 메모리 Grader output
1 Correct 122 ms 528 KB Ok! 1562 queries used.
2 Correct 122 ms 528 KB Ok! 1367 queries used.