답안 #35759

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
35759 2017-11-29T11:04:58 Z funcsr CEOI16_icc (CEOI16_icc) C++14
100 / 100
183 ms 2088 KB
#include "icc.h"
#include <iostream>
#include <vector>
#include <tuple>
#include <algorithm>
#include <set>
#include <cassert>
#define rep(i, n) for (int i=0; i<(n); i++)
#define pb push_back
#define all(x) x.begin(), x.end()

using namespace std;

int query(vector<int> a, vector<int> b) {
  if (a.empty() || b.empty()) return 0;
  int ar[100] = {}, br[100] = {};
  rep(i, a.size()) ar[i] = a[i]+1;
  rep(i, b.size()) br[i] = b[i]+1;
  return query(a.size(), b.size(), ar, br);
}

int N;
int U[100];
vector<int> R[100];
int find(int x) {
  if (U[x] == x) return x;
  return U[x] = find(U[x]);
}
void unite(int x, int y) {
  x = find(x), y = find(y);
  if (x == y) return;
  if (R[x].size() < R[y].size()) swap(x, y);
  U[y] = x;
  for (int t : R[y]) R[x].pb(t);
  R[y].clear();
}
vector<int> roots() {
  vector<int> ret;
  rep(i, N) if (find(i) == i) ret.pb(i);
  return ret;
}
int find(vector<int> X, vector<int> other) {
  if (X.size() == 1) return X[0];
  vector<int> a, b;
  rep(i, X.size()) {
    if (i&1) b.pb(X[i]);
    else     a.pb(X[i]);
  }
  if (query(a, other)) return find(a, other);
  else                 return find(b, other);
}

void run(int n) {
  N = n;
  rep(i, N) U[i] = i, R[i].pb(i);

  rep(_, N-1) {
    vector<int> vs = roots();
    int n = vs.size();
    int XOR = 0, X = -1;
    for (int e=0; (1<<e)<n; e++) {
      vector<int> Sa, Sb;
      rep(i, n) {
        if ((i>>e)&1) for (int x : R[vs[i]]) Sa.pb(x);
        else          for (int x : R[vs[i]]) Sb.pb(x);
      }
      if (query(Sa, Sb)) XOR ^= 1<<e, X = e;
    }
    int u = 0, v = 0;
    for (int e=0; (1<<e)<n; e++) {
      if (e == X) {
        v |= 1<<e;
        continue;
      }
      if ((XOR>>e)&1) {
        // a^b = 1
        vector<int> Sa, Sb;
        rep(i, n) {
          if (((i>>e)&1) != ((i>>X)&1)) continue;
          if ((i>>X)&1) for (int x : R[vs[i]]) Sa.pb(x);
          else          for (int x : R[vs[i]]) Sb.pb(x);
        }
        if (query(Sa, Sb)) v |= 1<<e;
        else               u |= 1<<e;
      }
      else {
        // a^b = 0
        vector<int> Sa, Sb;
        rep(i, n) {
          if ((i>>e)&1) continue;
          if ((i>>X)&1) for (int x : R[vs[i]]) Sa.pb(x);
          else          for (int x : R[vs[i]]) Sb.pb(x);
        }
        if (query(Sa, Sb)) u |= 0, v |= 0;
        else               u |= 1<<e, v |= 1<<e;
      }
    }
    assert((u^v) == XOR);

    int eu = find(R[vs[u]], R[vs[v]]);
    int ev = find(R[vs[v]], R[vs[u]]);
    unite(eu, ev);
    setRoad(eu+1, ev+1);
  }
}

Compilation message

icc.cpp: In function 'int query(std::vector<int>, std::vector<int>)':
icc.cpp:8:34: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
 #define rep(i, n) for (int i=0; i<(n); i++)
                                  ^
icc.cpp:17:3: note: in expansion of macro 'rep'
   rep(i, a.size()) ar[i] = a[i]+1;
   ^
icc.cpp:8:34: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
 #define rep(i, n) for (int i=0; i<(n); i++)
                                  ^
icc.cpp:18:3: note: in expansion of macro 'rep'
   rep(i, b.size()) br[i] = b[i]+1;
   ^
icc.cpp: In function 'int find(std::vector<int>, std::vector<int>)':
icc.cpp:8:34: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
 #define rep(i, n) for (int i=0; i<(n); i++)
                                  ^
icc.cpp:45:3: note: in expansion of macro 'rep'
   rep(i, X.size()) {
   ^
# 결과 실행 시간 메모리 Grader output
1 Correct 9 ms 2088 KB Ok! 114 queries used.
2 Correct 6 ms 2088 KB Ok! 112 queries used.
# 결과 실행 시간 메모리 Grader output
1 Correct 46 ms 2088 KB Ok! 638 queries used.
2 Correct 59 ms 2084 KB Ok! 558 queries used.
3 Correct 49 ms 2084 KB Ok! 630 queries used.
# 결과 실행 시간 메모리 Grader output
1 Correct 183 ms 2084 KB Ok! 1566 queries used.
2 Correct 123 ms 2088 KB Ok! 1365 queries used.
3 Correct 146 ms 2084 KB Ok! 1609 queries used.
4 Correct 139 ms 2088 KB Ok! 1583 queries used.
# 결과 실행 시간 메모리 Grader output
1 Correct 143 ms 2084 KB Ok! 1572 queries used.
2 Correct 136 ms 2084 KB Ok! 1565 queries used.
3 Correct 163 ms 2088 KB Ok! 1587 queries used.
4 Correct 139 ms 2084 KB Ok! 1591 queries used.
# 결과 실행 시간 메모리 Grader output
1 Correct 133 ms 2088 KB Ok! 1529 queries used.
2 Correct 143 ms 2084 KB Ok! 1556 queries used.
3 Correct 126 ms 2084 KB Ok! 1531 queries used.
4 Correct 146 ms 2088 KB Ok! 1587 queries used.
5 Correct 149 ms 2088 KB Ok! 1563 queries used.
6 Correct 139 ms 2088 KB Ok! 1600 queries used.
# 결과 실행 시간 메모리 Grader output
1 Correct 179 ms 2084 KB Ok! 1587 queries used.
2 Correct 156 ms 2084 KB Ok! 1556 queries used.