题解:CF2077B / CF2078E Finding OR Sum
Foreword
交互题。
Solution
考虑如何只需要两次询问确定每一位。
记 \(V_1,V_2\) 分别表示偶数位、奇数位全为一时的值,询问这两个值之后记得到的答案为 \(W_1,W_2\),你会发现与 \(x,y\) 按位或之后再减去原来的,也就是 \(W_1 - V_1,W_2 - V_2\) 的这两个值分别代表了 \(x,y\) 在奇数位、偶数位的情况。
我们记 \(k_1 = W_1-V_1,k_2 = W_2-V_2\),将 \(k_1.k_2\) 相邻两位从低位到高位分成一组,显然有 \(01,10,00\) 三种情况,\(00\) 的情况不用考虑,\(10\) 说明 \(x,y\) 在 \(1\) 的这一位上都为 \(1\),\(01\) 说明只有一个在 \(1\) 的这一位上为 \(1\)。
Code
#include <bits/stdc++.h>
#define int long long
using namespace std;
inline int Query (int x) {
cout << x << endl;
int tmp; cin >> tmp;
return tmp - x * 2;
}
inline void Solve() {
int V1 = 0, V2 = 0;
for (int i = 0; i < 30; i ++) {
if (i & 1) {
V2 |= (1 << i);
} else {
V1 |= (1 << i);
}
}
// V1 : 10101010101010101010101010101
// V2 : 10101010101010101010101010101
int x = 0, y = 0;
int v1 = Query (V2), v2 = Query (V1);
// 找到奇数偶数位的情况
for (int i = 0; i < 30; i ++) {
int tmp = ((i & 1) ? v2 : v1);
if ((tmp >> i) & 1) { // 01
x |= (1 << i);
} else if ((tmp >> (i + 1)) & 1) { // 10
x |= (1 << i), y |= (1 << i);
} else { // 00
continue;
}
}
cout << "!" << endl;
int m; cin >> m;
cout << (m | x) + (m | y) << endl;
return;
}
signed main() {
int Test;
cin >> Test;
while (Test --) Solve();
return 0;
}

浙公网安备 33010602011771号