E. Finding OR Sum
思路:
查询时选择…101010 和 …010101 这两种,分别覆盖偶数和奇数位。
每次查询返回的结果是(n|x) + (n|y)。由于n的某些位为1,这些位的贡献固定为2<<i,剩余的位(n中为0的位)的贡献由x和y的对应位决定。通过减去2*n,得到仅由n中0位贡献的差值,从而提取出x和y在这些位的组合信息
计算答案:根据m的每一位是否为1,选择对应的贡献值。若m的某位为1,贡献固定为2<<i;否则使用预先计算的位组合信息。
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define int long long
#define pb push_back
#define pii pair<int, int>
#define FU(i, a, b) for (int i = (a); i <= (b); ++i)
#define FD(i, a, b) for (int i = (a); i >= (b); --i)
const int MOD = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const int yl = 715827882, ly = 357913941;
void solve() {
int x1, x2;
cout << yl << endl;
cin >> x1;
x1 -= 2 * yl;
cout << ly << endl;
cin >> x2;
x2 -= 2 * ly;
int cnt[30] = {};
for (int i = 0; i < 30; i++) {
int b = (i % 2) ? x2 : x1;
if (b >> i & 1) {
cnt[i] = 1;
} else if (b >> (i + 1) & 1) {
cnt[i] = 2;
}
}
cout << "!" << endl;
int m;
cin >> m;
int ans = 0;
for (int i = 0; i < 30; i++) {
if (m >> i & 1) {
ans += 2 << i;
} else {
ans += cnt[i] << i;
}
}
cout << ans << endl;
}
signed main() {
int T = 1;
cin >> T;
while (T--) {
solve();
}
return 0;
}