Official

E - Bad Juice Editorial by en_translator


When you invite \(M\) friends, there are \(2^M\) possible pieces of information \(S\) on whether their stomach gets upset on the next day. Since there are \(N\) possibilities of the index of the bad juice, it is necessary that \(2^M \geq N\), i.e. \(M \geq \left\lceil \log_2 N \right\rceil\).

Conversely, it is sufficient to invite \(b \coloneqq \left\lceil \log_2 N\right\rceil\) friends. Indeed, you can utilize the \(b\) friends to determine the bad juice by the procedure below.

For convenience, we number juice and friends from \(0\), calling them \(0, 1, 2, \ldots, N-1\) and \(0, 1, 2, \ldots, b-1\), respectively. Here, \(2^b-1 \geq N-1\), so the index for any juice can be represented as \(b\)-digit binary. Let us call the digits the \(0\)-th, \(1\)-st, \(2\)-nd, \(\ldots\), and \((b-1)\)-th bit, from the least significant to the most. We serve juice to the each friend as follows:

For each pair \((i, j)\) of a friend \(i = 0, 1, 2, \ldots, b-1\) and a juice \(j = 0, 1, 2, \ldots, N-1\), we serve the \(j\)-th juice to the \(i\)-th friend if and only if the \(i\)-th bit of the binary representation of the juice index \(j\) is set.

This way, one can uniquely determine \(X\) from \(S\), because the \(0\)-th, \(1\)-st, \(2\)-nd, \(\ldots\), and \((b-1)\)-th digit of the binary representation of the index of the bad juice \(X\) coincide with the \(0\)-th, \(1\)-st, \(2\)-nd, \(\ldots\), and \((b-1)\)-th character of \(S\) (where the initial character is considered \(0\)-th).

The following is sample code in C++ language for this problem.

#include <iostream>
#include <vector>
using namespace std;

int main(void){
  int n;
  cin >> n;
  
  int b = 0;
  while((1<<b) < n) b++;
  cout << b << endl;
  
  for(int i = 0; i < b; i++){
    vector<int> avec;
    for(int j = 0; j < n; j++) if(j & (1<<i)) avec.push_back(j+1);
    cout << avec.size() << " ";
    for(auto a : avec) cout << a << " ";
    cout << endl;
  }
  
  string s;
  cin >> s;
  
  int ans = 0;
  for(int i = 0; i < b; i++) if(s[i] == '1') ans |= 1<<i;
  cout << ans+1 << endl;
  
  return 0;
}

posted:
last update: