| #include <iostream> |
| #include <vector> |
| #include <numeric> |
| #include <algorithm> |
| #include <cmath> |
|
|
| using namespace std; |
|
|
| |
| |
| |
| vector<int> query(const vector<int>& ops) { |
| if (ops.empty()) return {}; |
| cout << ops.size(); |
| for (int x : ops) cout << " " << x; |
| cout << endl; |
| |
| vector<int> res(ops.size()); |
| for (int i = 0; i < ops.size(); ++i) { |
| cin >> res[i]; |
| } |
| return res; |
| } |
|
|
| void answer(const vector<int>& p) { |
| cout << "-1"; |
| for (int x : p) cout << " " << x; |
| cout << endl; |
| exit(0); |
| } |
|
|
| int n; |
|
|
| int main() { |
| int subtask; |
| if (!(cin >> subtask >> n)) return 0; |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| vector<int> p(n); |
| iota(p.begin(), p.end(), 1); |
| |
| |
| vector<int> q1 = p; |
| vector<int> res1 = query(q1); |
| |
| vector<int> S_state; |
| vector<int> I1, R1; |
| for (int i = 0; i < n; ++i) { |
| if (res1[i] == 0) { |
| I1.push_back(p[i]); |
| } else { |
| R1.push_back(p[i]); |
| } |
| S_state.push_back(p[i]); |
| } |
| |
| |
| vector<int> q2 = S_state; |
| for (int x : R1) q2.push_back(x); |
| |
| vector<int> res2 = query(q2); |
| |
| |
| |
| vector<int> I2, R2; |
| for (int i = 0; i < R1.size(); ++i) { |
| int r = res2[S_state.size() + i]; |
| if (r == 0) { |
| I2.push_back(R1[i]); |
| } else { |
| R2.push_back(R1[i]); |
| } |
| } |
| |
| |
| |
| |
| |
| |
| |
| S_state = R1; |
| |
| vector<int> I3 = R2; |
| |
| vector<int> sets[3] = {I1, I2, I3}; |
| vector<int> node_set_id(n + 1); |
| for (int x : I1) node_set_id[x] = 0; |
| for (int x : I2) node_set_id[x] = 1; |
| for (int x : I3) node_set_id[x] = 2; |
|
|
| |
| |
| |
| |
| |
| int degree_ge1[3][n + 1]; |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| vector<int> q_deg[3]; |
| |
| |
| |
| |
| |
| |
| auto append_probe = [&](vector<int>& q, const vector<int>& targets) { |
| for (int u : targets) { |
| q.push_back(u); |
| q.push_back(u); |
| } |
| }; |
| |
| for (int t = 0; t < 3; ++t) { |
| |
| for (int x : S_state) q_deg[t].push_back(x); |
| |
| |
| for (int x : sets[t]) q_deg[t].push_back(x); |
| S_state = sets[t]; |
| |
| |
| vector<int> others; |
| for (int i = 0; i < 3; ++i) if (i != t) { |
| for (int x : sets[i]) others.push_back(x); |
| } |
| append_probe(q_deg[t], others); |
| } |
| |
| |
| for (int t = 0; t < 3; ++t) { |
| vector<int> res = query(q_deg[t]); |
| |
| |
| |
| |
| |
| |
| int offset = (int)q_deg[t].size() - 2 * (n - (int)sets[t].size()); |
| |
| vector<int> others; |
| for (int i = 0; i < 3; ++i) if (i != t) { |
| for (int x : sets[i]) others.push_back(x); |
| } |
| |
| for (int i = 0; i < others.size(); ++i) { |
| int u = others[i]; |
| int r = res[offset + 2 * i]; |
| degree_ge1[t][u] = r; |
| } |
| for (int x : sets[t]) degree_ge1[t][x] = 0; |
| } |
| |
| |
| int exact_deg[3][n + 1]; |
| for (int u = 1; u <= n; ++u) { |
| int my_set = node_set_id[u]; |
| int d[3] = {0, 0, 0}; |
| int sum_ge1 = 0; |
| for (int t = 0; t < 3; ++t) if (t != my_set) sum_ge1 += degree_ge1[t][u]; |
| |
| for (int t = 0; t < 3; ++t) { |
| if (t == my_set) { |
| exact_deg[t][u] = 0; |
| } else { |
| if (degree_ge1[t][u] == 0) exact_deg[t][u] = 0; |
| else { |
| |
| |
| if (sum_ge1 == 2) exact_deg[t][u] = 1; |
| else exact_deg[t][u] = 2; |
| } |
| } |
| } |
| } |
| |
| |
| vector<long long> neighbor_sum(n + 1, 0); |
| |
| for (int k = 0; k < 17; ++k) { |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| for (int t = 0; t < 3; ++t) { |
| for (int type = 0; type < 2; ++type) { |
| vector<int> q; |
| |
| for (int x : S_state) q.push_back(x); |
| |
| |
| vector<int> target_subset; |
| for (int x : sets[t]) { |
| int bit = (x >> k) & 1; |
| if ((type == 0 && bit == 1) || (type == 1 && bit == 0)) { |
| target_subset.push_back(x); |
| } |
| } |
| |
| for (int x : target_subset) q.push_back(x); |
| S_state = target_subset; |
| |
| |
| vector<int> others; |
| for (int i = 0; i < 3; ++i) if (i != t) { |
| for (int x : sets[i]) others.push_back(x); |
| } |
| append_probe(q, others); |
| |
| vector<int> res = query(q); |
| |
| int offset = (int)q.size() - 2 * (int)others.size(); |
| for (int i = 0; i < others.size(); ++i) { |
| int u = others[i]; |
| int r = res[offset + 2 * i]; |
| |
| |
| |
| |
| |
| |
| |
| |
| int deg = exact_deg[t][u]; |
| if (deg == 1) { |
| if (type == 0 && r == 1) { |
| neighbor_sum[u] += (1LL << k); |
| } |
| } else if (deg == 2) { |
| if (type == 0) { |
| if (r == 1) neighbor_sum[u] += (1LL << k); |
| } else { |
| if (r == 0) neighbor_sum[u] += (1LL << k); |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| |
| |
| |
| |
| |
| for (int start_node = 2; start_node <= n; ++start_node) { |
| vector<int> path; |
| path.push_back(1); |
| path.push_back(start_node); |
| |
| vector<bool> visited(n + 1, false); |
| visited[1] = true; |
| visited[start_node] = true; |
| |
| bool possible = true; |
| int curr = start_node; |
| int prev = 1; |
| |
| for (int i = 0; i < n - 2; ++i) { |
| long long next_sum = neighbor_sum[curr]; |
| int next = (int)(next_sum - prev); |
| if (next < 1 || next > n || visited[next]) { |
| possible = false; |
| break; |
| } |
| visited[next] = true; |
| path.push_back(next); |
| prev = curr; |
| curr = next; |
| } |
| |
| if (possible) { |
| |
| long long last_sum = neighbor_sum[curr]; |
| int closure = (int)(last_sum - prev); |
| if (closure == 1) { |
| |
| long long one_sum = neighbor_sum[1]; |
| if (one_sum - curr == start_node) { |
| answer(path); |
| } |
| } |
| } |
| } |
| |
| return 0; |
| } |