Strange Device

Strange Device

Created by LXC on Wed May 8 11:37:55 2024

https://codeforces.com/problemset/problem/1270/D

ranting: 1900

tag: constructive algorithms, interactive, math, sortings

problem

有一个长为 $n$ 数列 $a$,值已确定且值互不相等,但是你不知道。

现在有个设备,你可以输入长为 $k$ 的上升序列 $p_1,p_2 \dots p_k$,进行询问,它会回答 $a_{p_1},a_{p_2} \dots a_{p_k}$ 中第 $m$ 小的数在原数列的坐标和这个数的值。现在给你 $n$ 和 $k$,让你在最多询问 $n$ 次后回答 $m$ 的大小。保证一定可以构造出方案。

solution

先查询前k个数,得到结果值为$rt$,然后用第k+1个数对这k个数某一个进行替换,再查询。

如果结果值大于$rt$,说明是用了一个大于rt的值替换了小于等于rt的值。对k个值轮流替换再查询得到大于$rt$的结果数量实际上就是前k个数中小于等于rt的数量,也就是所求的m。

如果结果值小于$rt$,说明是用了一个小于rt的值替换了大于等于rt的值。对k个值轮流替换再查询得到小于$rt$的结果数量实际上就是前k个数中大于等于rt的数量,也就是k-m+1。

code

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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92

#include <bits/stdc++.h>
#define SINGLE_INPUT
#define ll long long
#define ull unsigned long long
#define N 500005
#define MOD 998244353
using namespace std;

random_device seed;
ranlux48 engine(seed());
int random(int l, int r) {
uniform_int_distribution<> distrib(l, r);
return distrib(engine);
}
template<class t,class u> ostream& operator<<(ostream& os,const pair<t,u>& p) {
return os<<'['<<p.first<<", "<<p.second<<']';
}
template<class t> ostream& operator<<(ostream& os,const vector<t>& v) {
os<<'['; int s = 1;
for(auto e:v) { if (s) s = 0; else os << ", "; os << e; }
return os<<']';
}
template<class t,class u> ostream& operator<<(ostream& os,const map<t,u>& mp){
os<<'{'; int s = 1;
for(auto [x,y]:mp) { if (s) s = 0; else os << ", "; os<<x<<": "<<y; }
return os<<'}';
}

vector<int> h = {2,1};
int m = 1;

pair<int,int> ask(vector<int>& v) {
cout << "?";
for (int i:v) {
cout << " " << i;
}
cout << endl;
// vector<pair<int,int>> r;
// for (int i:v) {
// r.emplace_back(i, h[i-1]);
// }
// sort(r.begin(), r.end(), [&](auto& x, auto& y) {
// return x.second < y.second;
// });
// return r[m-1];
pair<int,int> rt;
cin >> rt.first >> rt.second;
return rt;
}


void sol() {
int n = 2, k = 1;
cin >> n >> k;
vector<int> a(k);
iota(a.begin(), a.end(), 1);
int c = ask(a).second;
int u=0, d=0;
for (int i=0; i<k; i++) {
int t = a[i];
a[i] = k+1;
auto [p, v] = ask(a);
// cout << p << " " << v << endl;
if (v < c) u++;
else if (v > c) d++;
a[i] = t;
}
if (u) {
cout << "! " << k-u+1 << endl;
} else {
cout << "! " << d << endl;
}
}

int main() {
cout << setprecision(15) << fixed;
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
#ifndef SINGLE_INPUT
int t;
cin >> t;
while (t--) {
sol();
}
#else
sol();
#endif
return 0;
}