Search for a command to run...
Progressive hints first, then the full explanation and implementation when you're ready to cash out.
Review status
AI-generated and still unreviewed. Double-check the details before internalizing them.
Hints
Open only as much as you need to keep the solve alive.
Recovering all of is overkill. If you know just one bit , choose and whose -th bits are different; then the same bit of reveals .
Compare the first response with your query . Wherever they differ, the operation is forced: can only come from AND, while can only come from OR. In either case, that bit of equals the corresponding bit of .
Use . If , there is a differing bit and the previous observation finishes the test deterministically. If , the possible values of are exactly and the odd numbers.
In the branch, choose a uniformly random odd number and send . For , the response is exactly or . For nonzero , it is even when and odd when .
Decode with: if , answer ; else if , answer ; otherwise answer . The only failure is : among the possible odd values of , exactly one collides with the already-fixed nonzero odd .
The whole problem turns on one small observation: we do not need to recover either the operation or the complete value of . One known bit of is enough.
Suppose we know for some bit . Send
The -th bit of is exactly , so for the returned value ,
Therefore
That solves the test immediately once any bit of becomes known.
Let the first query be , and let the response be .
If some bit differs between and , only one operation could have caused that change:
| | | Forced operation | | |---:|---:|:---:|---:| | | | AND | | | | | OR | |
Thus, whenever , we know .
Now choose the extremely fancy query
Yes, just one. Bitmasks occasionally reward being aggressively boring.
There are three possibilities:
The first two cases are exactly the generic case: find a differing bit , send , and output .
Consider both possible operations:
Combining them, the possible values are
Consequently, every possible nonzero has known least significant bit . We only need to distinguish from a nonzero odd value.
After receiving the first query, the interactor is allowed to choose , so a deterministic second query can be targeted.
More generally, suppose and a deterministic algorithm sends . Put . We can construct two values as follows:
Then , , and . Hence
So the worlds and produce identical replies. A deterministic algorithm cannot always distinguish them.
The important timing detail is that all hidden values become fixed before we send . We can therefore use fresh private randomness after reading . The interactor gets to be annoying, but it does not get to be clairvoyant.
In the branch, choose uniformly among all odd integers in . There are exactly such integers. Send
The possible responses are:
| Hidden value | | | |:---|:---|:---| | | | | | nonzero odd | , which is even | , which is odd |
This gives the decoder:
For , one of the first two conditions always applies and is correct.
For odd with :
The sole bad event is . In that case, produces and produces , so both are mistaken for the corresponding cases.
Since is fixed before the uniformly random odd is chosen,
All other branches are deterministic. For at most tests, the union bound gives total failure probability at most
This is genuinely a Monte Carlo solution; the tiny failure probability is the point of the problem, not an implementation blemish.
Each test uses constant computation and constant memory. It performs exactly the required two query rounds. Every query and final answer must be flushed, and receiving must terminate the program immediately.
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
int main() {
setIO();
int t;
if (!(cin >> t)) return 0;
mt19937 rng((uint32_t)chrono::steady_clock::now().time_since_epoch().count());
uniform_int_distribution<int> pick(0, (1 << 29) - 1);
while (t--) {
cout << 1 << endl;
int o;
if (!(cin >> o) || o == -1) return 0;
if (o != 1) {
int bit = __builtin_ctz((unsigned)(o ^ 1));
cout << 0 << ' ' << (1 << bit) << endl;
int r;
if (!(cin >> r) || r == -1) return 0;
int b = ((r >> bit) & 1) ^ ((o >> bit) & 1);
cout << b << endl;
} else {
int q = 2 * pick(rng) + 1;
cout << q << ' ' << 0 << endl;
int r;
if (!(cin >> r) || r == -1) return 0;
int b;
if (r == q) b = 0;
else if (r == 0) b = 1;
else b = r & 1;
cout << b << endl;
}
}
}#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
int main() {
setIO();
int t;
if (!(cin >> t)) return 0;
mt19937 rng((uint32_t)chrono::steady_clock::now().time_since_epoch().count());
uniform_int_distribution<int> pick(0, (1 << 29) - 1);
while (t--) {
cout << 1 << endl;
int o;
if (!(cin >> o) || o == -1) return 0;
if (o != 1) {
int bit = __builtin_ctz((unsigned)(o ^ 1));
cout << 0 << ' ' << (1 << bit) << endl;
int r;
if (!(cin >> r) || r == -1) return 0;
int b = ((r >> bit) & 1) ^ ((o >> bit) & 1);
cout << b << endl;
} else {
int q = 2 * pick(rng) + 1;
cout << q << ' ' << 0 << endl;
int r;
if (!(cin >> r) || r == -1) return 0;
int b;
if (r == q) b = 0;
else if (r == 0) b = 1;
else b = r & 1;
cout << b << endl;
}
}
}