This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include "communication.h"
#include <bits/stdc++.h>
using namespace std;
vector<pair<int, int>> merge_vec(vector<pair<int, int>> x, vector<pair<int, int>> y) {
  int sz_x = x.size();
  int sz_y = y.size();
  int i = 0, j = 0;
  vector<pair<int, int>> res;
  while (i < sz_x || j < sz_y) {
    if (j == sz_y || (i < sz_x && x[i].first < y[j].first)) {
      if (res.empty() || res.back().second != x[i].first - 1) {
        res.push_back(x[i]);
      } else {
        res.back().second = x[i].second;
      }
      i++;
    } else {
      if (res.empty() || res.back().second != y[j].first - 1) {
        res.push_back(y[j]);
      } else {
        res.back().second = y[j].second;
      }
      j++;
    }
  }
  return res;
}
struct state {
  vector<pair<int, int>> interval;
  int len;
  state(int N) {
    if (N == -1) {
      len = 0;
      interval = {};
    } else {
      len = N;
      interval = {make_pair(1, N)};
    }
  }
  void add(pair<int, int> p) {
    interval = merge_vec(interval, {p});
    len += p.second - p.first + 1;
  }
  bool in(int x) {
    for (auto& p : interval) {
      if (p.first <= x && x <= p.second) {
        return true;
      }
    }
    return false;
  }
  pair<state, state> split(int delta) {
    state L(-1);
    state R(-1);
    if (len == 0) {
      return {L, R};
    }
    for (auto& p : interval) {
      if (L.len + p.second - p.first + 1 <= (len + delta) / 2) {
        L.add(p);
      } else if (L.len >= (len + delta) / 2) {
        R.add(p);
      } else {
        L.add({p.first, p.first + (len + delta) / 2 - L.len - 1});
        assert(!L.interval.empty());
        R.add({L.interval.back().second + 1, p.second});
      }
    }
    return {L, R};
  }
  vector<int> all() {
    vector<int> v;
    for (auto& p : interval) {
      for (int i = p.first; i <= p.second; i++) {
        v.push_back(i);
      }
    }
    return v;
  }
};
state Merge(state p, state q) {
  state ret(-1);
  ret.interval = merge_vec(p.interval, q.interval);
  ret.len = p.len + q.len;
  return ret;
}
pair<int, int> solve(int N, int X) {
  state good(N);
  state bad(-1);
  while (good.len + bad.len > 3) {
    auto good_split = good.split(0);
    state good_L = good_split.first;
    state good_R = good_split.second;
    auto bad_split = bad.split(1);
    state bad_L = bad_split.first;
    state bad_R = bad_split.second;
//    cout << "good_L = ";
//    for (auto& p : good_L.interval) {
//      cout << p.first << " " << p.second << '\n';
//    }
//    cout << '\n';
//    cout << "good_R = ";
//    for (auto& p : good_R.interval) {
//      cout << p.first << " " << p.second << '\n';
//    }
//    cout << '\n';
//    cout << "bad_L = ";
//    for (auto& p : bad_L.interval) {
//      cout << p.first << " " << p.second << '\n';
//    }
//    cout << '\n';
//    cout << "bad_R = ";
//    for (auto& p : bad_R.interval) {
//      cout << p.first << " " << p.second << '\n';
//    }
//    cout << '\n';
    int f;
    if (X == -1) {
      f = receive();
    } else {
      f = send(good_L.in(X) || bad_L.in(X));
    }
    if (f == 0) {
      good = Merge(good_R, bad_R);
      bad = good_L;
    } else {
      good = Merge(good_L, bad_L);
      bad = good_R;
    }
  }
  vector<int> nums = Merge(good, bad).all();
  if (nums.size() == 3) {
    if (X != -1) {
      if (nums[0] == X) {
        send(0);
        send(0);
        send(0);
        send(0);
      }
      if (nums[1] == X) {
        send(0);
        send(1);
        send(1);
        send(0);
      }
      if (nums[2] == X) {
        send(1);
        send(1);
        send(1);
        send(1);
      }
    } else {
      vector<vector<int>> f;
      f.push_back({0, 0, 0, 0});
      f.push_back({0, 1, 1, 0});
      f.push_back({1, 1, 1, 1});
      vector<int> seq;
      seq.push_back(receive());
      seq.push_back(receive());
      seq.push_back(receive());
      seq.push_back(receive());
      vector<int> new_nums;
      for (int i = 0; i < 3; i++) {
        bool ok = true;
        for (int j = 1; j < 4; j++) {
          if (seq[j] != f[i][j] && seq[j - 1] != f[i][j - 1]) {
            ok = false;
          }
        }
        if (ok) {
          new_nums.push_back(nums[i]);
        }
      }
      swap(new_nums, nums);
    }
  }
  if (nums.size() == 1) {
    return {nums[0], nums[0]};
  }
  return {nums[0], nums[1]};
}
void encode(int N, int X) {
  solve(N, X);
}
pair<int, int> decode(int N) {
  return solve(N, -1);
}
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... |