Problem: abc313_d
Difficulty: medium
Categories: math
Time limit: 2000 ms, memory limit: 1024 MB

### Problem Statement

This is an **interactive task** (where your program and the judge interact via Standard Input and Output).

You are given an integer $N$ and an **odd number** $K$.  
The judge has a hidden length-$N$ sequence $A = (A_1, A_2, \dots, A_N)$ consisting of $0$ and $1$.

While you cannot directly access the elements of sequence $A$,
you are allowed to ask the judge the following query at most $N$ times.

* Choose distinct integers $x_1, x_2, \dots$, and $x_K$ between $1$ and $N$, inclusive, to ask the parity of $A_{x_1} + A_{x_2} + \dots + A_{x_K}$.

Determine $(A_1, A_2, \dots, A_N)$ by at most $N$ queries, and print the answer.  
Here, **the judge is adaptive**. In other words, the judge may modify the contents of $A$ as long as it is consistent with the responses to the past queries.  
Therefore, your program is considered correct if the output satisfies the following condition, and incorrect otherwise:

* your program prints a sequence consistent with the responses to the queries so far, and that is the only such sequence.

### Constraints

* $1 \leq K \lt N \leq 1000$
* $K$ is odd.
* $A_i$ is $0$ or $1$.

### Input and Output

This is an **interactive task** (where your program and the judge interact via Standard Input and Output).

First of all, receive $N$ and $K$ from Standard Input.

```
$N$ $K$
```

Then, repeat asking queries until you can uniquely determine $(A_1, A_2, \dots, A_N)$.  
Each query should be printed to Standard Output in the following format, where $x_1, x_2, \dots$, and $x_K$ are $K$ distinct integers between $1$ and $N$, inclusive.

```
$?$ $x_1$ $x_2$ $\dots$ $x_K$
```

The response to the query is given from Standard Input in the following format.

```
$T$
```

Here, $T$ denotes the response to the query.

* $T$ is `0` when $A_{x_1} + A_{x_2} + \dots + A_{x_K}$ is even, and
* $T$ is `1` when $A_{x_1} + A_{x_2} + \dots + A_{x_K}$ is odd.

However, if $x_1, x_2, \dots$ and $x_K$ do not satisfy the constraints, or the number of queries exceeds $N$, then $T$ is `-1`.

If the judge returns `-1`, your program is already considered incorrect, so terminate the program immediately.

When you can determine all the elements of $A$, print those elements in the following format, and terminate the program immediately.

```
$!$ $A_1$ $A_2$ $\dots$ $A_N$
```

### Notes

* **Print a newline and flush Standard Output at the end of each message. Otherwise, you may get a TLE verdict.**
* **The verdict will be indeterminate if there is malformed output during the interaction or your program quits prematurely.**
* Terminate the program immediately after printing the answer, or the verdict will be indeterminate.
* The judge for this problem is adaptive. This means that the judge may modify the contents of $A$ as long as it is consistent with the responses to the past queries.

### Sample Interaction

In the following interaction, $N=5$ and $K=3$. **Note that the following output itself will result in WA.**  
Here, $A = (1, 0, 1, 1, 0)$ is indeed consistent with the responses, but so is $(0, 0, 1, 0, 0)$, so sequence $A$ is not uniquely determined. Thus, this program is considered incorrect.

| Input | Output | Description |
| --- | --- | --- |
| `5 3` |  | First, you are given integers $N$ and $K$. |
|  | `? 2 4 1` | You ask a query with $(x_1, x_2, x_3) = (2, 4, 1)$. |
| `0` |  | The response to the query is $0$, so the judge returns that value. |
|  | `? 5 3 2` | You ask a query with $(x_1, x_2, x_3) = (5, 3, 2)$. |
| `1` |  | The response to the query is $1$, so the judge returns that value. |
|  | `! 1 0 1 1 0` | You print $(1, 0, 1, 1, 0)$ to guess $A$. Since sequence $A$ is not uniquely determined, the verdict will be WA. |

Non-adaptive interactor (C++):
#include "testlib.h"
#include <bits/stdc++.h>
using namespace std;


static long long queries = 0;
static long long query_limit = 0;


static void log_metrics() {
    try {
        tout << "queries=" << queries << endl;
        tout << "query_limit=" << query_limit << endl;
    } catch (...) {
        
    }
}


static void finish(TResult verdict, const string& msg) {
    log_metrics();
    quitf(verdict, "%s", msg.c_str());
}

int main(int argc, char** argv) {
    
    registerInteraction(argc, argv);
    
    
    tout.open(argv[2]);

    
    atexit(log_metrics);

    
    
    int N = inf.readInt(2, 1000, "N");
    int K = inf.readInt(1, N - 1, "K");
    
    
    if (K % 2 == 0) {
        finish(_fail, "K must be odd according to constraints");
    }

    
    vector<int> A(N);
    for (int i = 0; i < N; i++) {
        A[i] = inf.readInt(0, 1, format("A[%d]", i + 1));
    }

    
    query_limit = N;
    long long hard_cap = max(200000LL, 10LL * query_limit);

    
    cout << N << " " << K << endl;

    string token;
    while (cin >> token) {
        
        if (token == "!") {
            vector<int> guess(N);
            for (int i = 0; i < N; i++) {
                if (!(cin >> guess[i])) {
                    finish(_pe, "Could not read answer element " + to_string(i + 1));
                }
                if (guess[i] != 0 && guess[i] != 1) {
                    finish(_pe, "Answer elements must be 0 or 1");
                }
            }

            
            if (guess == A) {
                finish(_ok, "Correct sequence");
            } else {
                finish(_wa, "Incorrect sequence");
            }
            return 0; 
        }

        
        vector<int> indices;
        indices.reserve(K);

        
        if (token == "?") {
            
            for (int i = 0; i < K; i++) {
                int val;
                if (!(cin >> val)) finish(_pe, "Failed to read query index");
                indices.push_back(val);
            }
        } else {
            
            try {
                size_t pos;
                int val = stoi(token, &pos);
                if (pos != token.size()) finish(_pe, "Invalid token in query: " + token);
                indices.push_back(val);
            } catch (...) {
                finish(_pe, "Invalid token in query: " + token);
            }
            
            for (int i = 1; i < K; i++) {
                int val;
                if (!(cin >> val)) finish(_pe, "Failed to read query index");
                indices.push_back(val);
            }
        }

        
        vector<int> sorted_idxs = indices;
        sort(sorted_idxs.begin(), sorted_idxs.end());
        bool distinct = true;
        for (int i = 0; i < K; i++) {
            if (sorted_idxs[i] < 1 || sorted_idxs[i] > N) {
                finish(_pe, "Query index out of range: " + to_string(sorted_idxs[i]));
            }
            if (i > 0 && sorted_idxs[i] == sorted_idxs[i-1]) {
                distinct = false;
            }
        }
        if (!distinct) {
            finish(_pe, "Query indices must be distinct");
        }

        
        queries++;
        
        
        if (queries % 10 == 0) log_metrics();

        
        if (queries > hard_cap) {
            finish(_pe, "Hard query limit exceeded");
        }

        
        int sum_val = 0;
        for (int idx : indices) {
            sum_val += A[idx - 1];
        }
        
        cout << (sum_val % 2) << endl;
    }

    
    finish(_pe, "Unexpected EOF (did not receive answer)");
}


Adaptive interactor (C++):
#include "testlib.h"
#include <bits/stdc++.h>

using namespace std;


static long long queries = 0;
static long long query_limit = 0;
static bool finished = false;


static void log_metrics() {
    if (!tout.is_open()) return;
    tout << "queries=" << queries << endl;
    tout << "query_limit=" << query_limit << endl;
}


static void finish(TResult verdict, const string& msg) {
    if (finished) return;
    finished = true;
    log_metrics();
    quitf(verdict, "%s", msg.c_str());
}


void cleanup() {
    if (!finished) log_metrics();
}


const int MAXN = 1005;

struct LinearBasis {
    int N;
    
    bitset<MAXN> basis[MAXN];
    
    int rhs[MAXN];
    int rank;

    LinearBasis(int n) : N(n), rank(0) {
        for (int i = 0; i < N; ++i) rhs[i] = 0;
    }

    
    
    
    int query(const vector<int>& indices) {
        bitset<MAXN> vec;
        for (int x : indices) vec.set(x - 1); 

        int current_val = 0;

        
        for (int i = 0; i < N; ++i) {
            if (!vec.test(i)) continue; 

            if (basis[i].any()) {
                
                vec ^= basis[i];
                current_val ^= rhs[i];
            } else {
                
                
                
                basis[i] = vec;
                rhs[i] = current_val;
                rank++;
                return 0; 
            }
        }

        
        
        return current_val;
    }

    
    
    vector<int> get_unique_solution() {
        if (rank < N) return {};

        vector<int> res(N);
        
        for (int i = N - 1; i >= 0; --i) {
            int val = rhs[i];
            for (int j = i + 1; j < N; ++j) {
                if (basis[i].test(j)) {
                    val ^= res[j];
                }
            }
            res[i] = val;
        }
        return res;
    }
};

int main(int argc, char* argv[]) {
    
    registerInteraction(argc, argv);
    atexit(cleanup);

    
    
    int n = inf.readInt();
    int k = inf.readInt();

    
    query_limit = n;

    
    cout << n << " " << k << endl;

    LinearBasis lb(n);
    
    long long hard_cap = max(20000LL, 10 * query_limit);

    
    while (true) {
        string token;
        
        if (!(cin >> token)) {
            finish(_wa, "Unexpected end of output from contestant");
        }

        if (token == "?") {
            queries++;

            
            vector<int> q(k);
            vector<int> distinct_check;
            distinct_check.reserve(k);

            for (int i = 0; i < k; ++i) {
                if (!(cin >> q[i])) {
                    finish(_wa, "Malformed query: expected integer");
                }
                
                if (q[i] < 1 || q[i] > n) {
                    finish(_wa, format("Query index %d out of range [1, %d]", q[i], n));
                }
                distinct_check.push_back(q[i]);
            }

            
            sort(distinct_check.begin(), distinct_check.end());
            if (unique(distinct_check.begin(), distinct_check.end()) != distinct_check.end()) {
                finish(_wa, "Query indices must be distinct");
            }

            
            if (queries > query_limit) {
                
                cout << -1 << endl;
                finish(_wa, "Query limit exceeded");
            }

            
            if (queries > hard_cap) {
                finish(_pe, "Too many queries (hard cap exceeded)");
            }

            
            int ans = lb.query(q);
            cout << ans << endl;

        } else if (token == "!") {
            
            vector<int> user_ans(n);
            for (int i = 0; i < n; ++i) {
                if (!(cin >> user_ans[i])) {
                    finish(_wa, "Malformed final answer");
                }
                if (user_ans[i] != 0 && user_ans[i] != 1) {
                    finish(_wa, "Answer elements must be 0 or 1");
                }
            }

            
            vector<int> expected = lb.get_unique_solution();
            
            if (expected.empty()) {
                
                finish(_wa, "Sequence A is not uniquely determined by the queries asked");
            } else {
                if (user_ans == expected) {
                    finish(_ok, "Correct");
                } else {
                    finish(_wa, "Incorrect sequence");
                }
            }
            
        } else {
            finish(_wa, format("Expected '?' or '!', found '%s'", token.c_str()));
        }
    }

    return 0;
}


Test generator (C++):
#include "testlib.h"
#include <bits/stdc++.h>

using namespace std;

int main(int argc, char* argv[]) {
    registerGen(argc, argv, 1);

    
    string mode = opt<string>("mode", "non");
    long long seed_val = 0;
    if (argc > 1) seed_val = atoll(argv[1]);

    int N = opt<int>("n", 0);
    int K = opt<int>("k", 0);

    
    if (N == 0) {
        if (seed_val == 1) {
            
            N = 2; K = 1;
        } else if (seed_val == 2) {
            
            N = 1000; K = 1;
        } else if (seed_val == 3) {
            
            N = 1000; K = 999;
        } else if (seed_val == 4) {
            
            N = 1000; K = 501;
        } else if (seed_val == 5) {
            
            N = 50; K = 25;
        } else if (seed_val <= 10) {
            
            N = rnd.next(2, 20);
        } else {
            
            N = rnd.next(2, 1000);
        }
    }

    
    if (K == 0) {
        
        
        int max_K = N - 1 - (N % 2);
        if (max_K < 1) max_K = 1; 

        
        
        int num_odds = (max_K + 1) / 2;
        int idx = rnd.next(0, num_odds - 1);
        K = 2 * idx + 1;
    }

    
    if (N < 2) N = 2;
    if (N > 1000) N = 1000;
    
    
    
    if (K >= N) K = N - 1 - (N % 2);
    if (K < 1) K = 1;
    
    if (K % 2 == 0) K--;

    
    cout << N << " " << K << endl;

    
    if (mode == "non") {
        vector<int> A(N);
        
        int type = rnd.next(1, 10);
        if (type == 1) {
            
            fill(A.begin(), A.end(), 0);
        } else if (type == 2) {
            
            fill(A.begin(), A.end(), 1);
        } else if (type == 3) {
            
            for (int i = 0; i < N; i++) A[i] = i % 2;
        } else {
            
            for (int i = 0; i < N; i++) A[i] = rnd.next(0, 1);
        }
        println(A);
    }
    
    

    return 0;
}