| #include <iostream> |
| #include <vector> |
| #include <numeric> |
| #include <algorithm> |
| #include <random> |
| #include <map> |
|
|
| using namespace std; |
|
|
| |
| void fast_io() { |
| ios_base::sync_with_stdio(false); |
| cin.tie(NULL); |
| } |
|
|
| |
| |
| 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; |
| } |
|
|
| int main() { |
| fast_io(); |
| int subtask, n; |
| if (!(cin >> subtask >> n)) return 0; |
|
|
| |
| |
| |
| |
| |
| vector<int> p(n); |
| iota(p.begin(), p.end(), 1); |
| |
| mt19937 rng(1337); |
| shuffle(p.begin(), p.end(), rng); |
| |
| vector<int> remaining = p; |
| vector<vector<int>> layers; |
| |
| for (int k = 0; k < 5 && !remaining.empty(); ++k) { |
| |
| |
| |
| vector<int> ops = remaining; |
| vector<int> res = query(ops); |
| |
| vector<int> layer, next_rem; |
| for (int i = 0; i < remaining.size(); ++i) { |
| if (res[i] == 0) { |
| layer.push_back(remaining[i]); |
| } else { |
| next_rem.push_back(remaining[i]); |
| } |
| } |
| layers.push_back(layer); |
| remaining = next_rem; |
| } |
| if (!remaining.empty()) { |
| layers.push_back(remaining); |
| } |
| |
| int num_layers = layers.size(); |
| |
| |
| vector<int> local_idx(n + 1); |
| vector<int> layer_id(n + 1); |
| for (int i = 0; i < num_layers; ++i) { |
| for (int j = 0; j < layers[i].size(); ++j) { |
| int u = layers[i][j]; |
| local_idx[u] = j; |
| layer_id[u] = i; |
| } |
| } |
| |
| |
| |
| vector<map<int, pair<int, int>>> node_data(n + 1); |
|
|
| |
| |
| |
| for (int batch = 0; batch < 2; ++batch) { |
| vector<int> batch_ops; |
| struct Rec { |
| int u; |
| int target_layer; |
| int bit; |
| int val; |
| int res_idx; |
| }; |
| vector<Rec> records; |
| |
| int start_bit = batch * 8; |
| int end_bit = min((batch + 1) * 8, 16); |
| |
| for (int b = start_bit; b < end_bit; ++b) { |
| for (int i = 0; i < num_layers; ++i) { |
| for (int j = 0; j < num_layers; ++j) { |
| if (i == j) continue; |
| |
| for (int val = 0; val <= 1; ++val) { |
| vector<int> mask; |
| for (int v : layers[j]) { |
| if (((local_idx[v] >> b) & 1) == val) { |
| mask.push_back(v); |
| } |
| } |
| if (mask.empty()) continue; |
| |
| |
| batch_ops.insert(batch_ops.end(), mask.begin(), mask.end()); |
| int current_op_idx = batch_ops.size(); |
| |
| |
| for (int u : layers[i]) { |
| batch_ops.push_back(u); |
| records.push_back({u, j, b, val, current_op_idx}); |
| current_op_idx++; |
| |
| batch_ops.push_back(u); |
| current_op_idx++; |
| } |
| |
| |
| batch_ops.insert(batch_ops.end(), mask.begin(), mask.end()); |
| } |
| } |
| } |
| } |
| |
| vector<int> res = query(batch_ops); |
| |
| for (const auto& r : records) { |
| |
| if (res[r.res_idx] == 1) { |
| if (r.val == 0) node_data[r.u][r.target_layer].first |= (1 << r.bit); |
| else node_data[r.u][r.target_layer].second |= (1 << r.bit); |
| } |
| } |
| } |
| |
| |
| vector<vector<int>> adj(n + 1); |
| |
| |
| struct Candidate { |
| int u; |
| int diff; |
| int common; |
| int target_layer; |
| }; |
| vector<Candidate> cands; |
| |
| for (int u = 1; u <= n; ++u) { |
| for (auto& entry : node_data[u]) { |
| int lay = entry.first; |
| int m0 = entry.second.first; |
| int m1 = entry.second.second; |
| |
| |
| if (m0 == 0 && m1 == 0) continue; |
| |
| int diff = m0 & m1; |
| int common = m1 & (~m0); |
| |
| if (diff == 0) { |
| |
| int idx = common; |
| if (idx < layers[lay].size()) { |
| int v = layers[lay][idx]; |
| adj[u].push_back(v); |
| adj[v].push_back(u); |
| } |
| } else { |
| |
| cands.push_back({u, diff, common, lay}); |
| } |
| } |
| } |
| |
| |
| for (const auto& c : cands) { |
| int u = c.u; |
| |
| |
| for (int v : layers[c.target_layer]) { |
| int v_idx = local_idx[v]; |
| |
| |
| if ((v_idx & ~c.diff) == c.common) { |
| |
| int u_layer = layer_id[u]; |
| if (node_data[v].count(u_layer)) { |
| int vm0 = node_data[v][u_layer].first; |
| int vm1 = node_data[v][u_layer].second; |
| int v_diff = vm0 & vm1; |
| int v_common = vm1 & (~vm0); |
| |
| int u_idx_val = local_idx[u]; |
| if ((u_idx_val & ~v_diff) == v_common) { |
| adj[u].push_back(v); |
| adj[v].push_back(u); |
| } |
| } |
| } |
| } |
| } |
| |
| |
| for (int i = 1; i <= n; ++i) { |
| sort(adj[i].begin(), adj[i].end()); |
| adj[i].erase(unique(adj[i].begin(), adj[i].end()), adj[i].end()); |
| } |
| |
| vector<int> ans; |
| vector<bool> visited(n + 1, false); |
| int curr = 1; |
| |
| |
| for(int i=1; i<=n; ++i) if(adj[i].size() > 0) { curr = i; break; } |
| |
| |
| for (int i = 0; i < n; ++i) { |
| ans.push_back(curr); |
| visited[curr] = true; |
| int next = -1; |
| for (int v : adj[curr]) { |
| if (!visited[v]) { |
| next = v; |
| break; |
| } |
| } |
| if (next == -1 && i < n - 1) { |
| |
| |
| |
| |
| } else { |
| curr = next; |
| } |
| } |
| |
| cout << "-1"; |
| for (int x : ans) cout << " " << x; |
| cout << endl; |
| |
| return 0; |
| } |