[CF1363D] Guess The Maximums
Description
给定序列 (a) 的长度 (n) 和 (k) 个互不相交的子集 (S_i),每次查询可以输出一些下标 (q_1,q_2,...,q_c) 并得到序列中这些位置的数的最大值。对每个子集 (S_i),求出序列 a 中不在该子集下标范围内的最大值。
Solution
通过不超过 11 次询问找出序列中最大值的下标 m,含有 m 的子集显然只有一个 (S_x),则对任意 (S_i, i eq x) 其答案显然为 m,对于 (S_x),我们手动求一次不在该子集内的最大值即可。
#include <bits/stdc++.h>
using namespace std;
#define int long long
int make_query(int l, int r)
{
cout << "? " << r - l + 1 << " ";
for (int i = l; i <= r; i++)
cout << i << " ";
cout << endl;
int ans = 0;
cin >> ans;
return ans;
}
signed main()
{
int t;
cin >> t;
while (t--)
{
int n, k;
cin >> n >> k;
vector<int> qid(n + 2);
for (int i = 1; i <= k; i++)
{
int size;
cin >> size;
for (int j = 1; j <= size; j++)
{
int t;
cin >> t;
qid[t] = i;
}
}
int l = 1, r = n;
int max_value = make_query(1, n);
while (l < r)
{
int mid = (l + r) / 2;
if (make_query(l, mid) == max_value)
r = mid;
else
l = mid + 1;
}
int m = l;
vector<int> vec;
for (int i = 1; i <= n; i++)
if ((qid[i] != qid[m]) || !qid[m])
vec.push_back(i);
cout << "? " << vec.size() << " ";
for (auto i : vec)
cout << i << " ";
cout << endl;
int ans;
cin >> ans;
cout << "! ";
for (int i = 1; i <= k; i++)
if (i == qid[m])
cout << ans << " ";
else
cout << max_value << " ";
cout << endl;
string cor;
cin >> cor;
}
}