duel 到了这种题也是幸运,但是这题评测好慢。

如果不知道 pp 序列是什么肯定没有做法,发现我们花掉 nn 次的代价之后剩余的 3030 次一定是能把答案处理出来的,因为给我们返回的结果有单调性,mm 也不超过 2302^{30}

因此只需要先求出 pp,然后直接二分,同时根据 pp 对应的说不说谎推出当前中间点的结果就好啦。

注意题目不能问大于 mm 的数,所以找 pp 的时候如果每次询问 mm 拿到了一个 00 就直接退出就好了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include<bits/stdc++.h>
using namespace std;
#define int long long
int ask(int x)
{
cout << x << '\n';
cout.flush();
cin >> x;
return x;
}
signed main()
{
int n, m;
cin >> m >> n; // 一开始写反了
vector<int> v;
for (int i = 0; i < n; i++) {
int res = ask(m);
if (res == 0) {
exit(0);
}
v.push_back(res == 1 ? 1 : -1);
}
int l = 1, r = m, cnt = 0;
while (l <= r) {
int mid = (l + r) / 2;
int res = v[cnt % n] * ask(mid);
if (res == 0) {
exit(0);
}
if (res == 1) {
r = mid - 1;
} else {
l = mid + 1;
}
cnt++;
}
return 0;
}