Problem: cf1698_d
Difficulty: medium
Categories: search, math
Time limit: 1000 ms, memory limit: 256 MB

This is an interactive problem.

Initially, there is an array $a = [1, 2, \ldots, n]$, where $n$ is an odd positive integer. The jury has selected $\frac{n-1}{2}$ disjoint pairs of elements, and then the elements in those pairs are swapped. For example, if $a=[1,2,3,4,5]$, and the pairs $1 \leftrightarrow 4$ and $3 \leftrightarrow 5$ are swapped, then the resulting array is $[4, 2, 5, 1, 3]$.

As a result of these swaps, exactly one element will not change position. You need to find this element.

To do this, you can ask several queries. In each query, you can pick two integers $l$ and $r$ ($1 \leq l \leq r \leq n$). In return, you will be given the elements of the subarray $[a_l, a_{l + 1}, \dots, a_r]$ sorted in increasing order.

Find the element which did not change position. You can make at most $\mathbf{15}$ queries.

The array $a$ is fixed before the interaction and does not change after your queries.

Recall that an array $b$ is a subarray of the array $a$ if $b$ can be obtained from $a$ by deletion of several (possibly, zero or all) elements from the beginning and several (possibly, zero or all) elements from the end.

Input

Each test contains multiple test cases. The first line contains an integer $t$ ($1 \leq t \leq 500$) — the number of test cases. The description of the test cases follows.

The first line of each test case contains an integer $n$ ($3 \leq n < 10^4$; $n$ is odd) — the length of the array $a$.

After reading the first line of each test case, you should begin the interaction.

It is guaranteed that the sum of $n$ over all test cases does not exceed $10^4$.

Interaction

For each test case, begin the interaction by reading the integer $n$.

To make a query, output "$\texttt{?}\;l\;r$" ($1 \leq l \leq r \leq n$) without quotes. Afterwards, you should read in $r-l+1$ integers — the integers $a_l, a_{l + 1}, \dots, a_r$, in increasing order. You can make at most $15$ such queries in a single test case.

If you receive the integer $-1$ instead of an answer or the integer $n$, it means your program has made an invalid query, has exceed the limit of queries, or has given incorrect answer on the previous test case. Your program must terminate immediately to receive a Wrong Answer verdict. Otherwise you can get an arbitrary verdict because your solution will continue to read from a closed stream.

When you are ready to give the final answer, output "$\texttt{!}\;x$" ($1 \leq x \leq n$) without quotes — the element that did not change position. Giving this answer does not count towards the limit of $15$ queries. Afterwards, your program must continue to solve the remaining test cases, or exit if all test cases have been solved.

After printing a query do not forget to output end of line and flush the output. Otherwise, you will get Idleness limit exceeded. To do this, use:

* fflush(stdout) or cout.flush() in C++;
* System.out.flush() in Java;
* flush(output) in Pascal;
* stdout.flush() in Python;
* see documentation for other languages.

Example

Input

```
2
5

1 2 4 5

1 3 5

3

1
```

Output

```
? 1 4

? 3 5

! 2

? 1 1

! 1
```

Note

In the first test, the interaction proceeds as follows.

|  |  |  |
| --- | --- | --- |
| Solution | Jury | Explanation |
|  | $\texttt{2}$ | There are 2 test cases. |
|  | $\texttt{5}$ | In the first test case, the hidden array is $[4,2,5,1,3]$, with length $5$. |
| $\texttt{? 1 4}$ | $\texttt{1 2 4 5}$ | The solution requests the subarray $[4,2,5,1]$ in increasing order, and the jury responds with $[1,2,4,5]$. |
| $\texttt{? 3 5}$ | $\texttt{1 3 5}$ | The solution requests the subarray $[5,1,3]$ in increasing order, and the jury responds with $[1,3,5]$. |
| $\texttt{! 2}$ |  | The solution has somehow determined that $a_2=2$, and outputs it. Since the output is correct, the jury continues to the next test case. |
|  | $\texttt{3}$ | In the second test case, the hidden array is $[1,3,2]$, with length $3$. |
| $\texttt{? 1 1}$ | $\texttt{1}$ | The solution requests the number $[1]$ only, and the jury responds with $[1]$. |
| $\texttt{! 1}$ |  | The solution has determined that $a_1=1$, and outputs it. Since the output is correct and there are no more test cases, the jury and the solution exit. |

Note that the line breaks in the example input and output are for the sake of clarity, and do not occur in the real interaction.

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












static long long queries = 0;      
static long long query_limit = 15; 
static const long long HARD_CAP = 200000; 

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);
    atexit(log_metrics);

    
    int t = inf.readInt();
    cout << t << endl; 

    long long total_ops = 0;

    for (int i = 0; i < t; ++i) {
        
        int n = inf.readInt();
        vector<int> a(n + 1);
        int ans = -1;
        
        
        for (int j = 1; j <= n; ++j) {
            a[j] = inf.readInt();
            if (a[j] == j) {
                ans = j;
            }
        }

        if (ans == -1) {
            finish(_fail, "Invalid hidden input: no fixed point found in permutation");
        }

        
        cout << n << endl;

        int current_case_queries = 0;
        
        
        log_metrics();

        while (true) {
            if (++total_ops > HARD_CAP) {
                finish(_pe, "Hard interaction limit exceeded (solution spamming or infinite loop)");
            }

            string token;
            if (!(cin >> token)) {
                finish(_pe, "Unexpected EOF from solution");
            }
            
            bool is_ans = false;
            bool is_query = false;
            int l = -1, r = -1, x = -1;

            
            if (token[0] == '!') {
                is_ans = true;
                if (token.size() > 1) {
                    
                    try { x = stoi(token.substr(1)); }
                    catch (...) { finish(_pe, "Invalid integer format after '!'"); }
                } else {
                    
                    if (!(cin >> x)) finish(_pe, "Expected integer after '!'");
                }
            } else if (token[0] == '?') {
                is_query = true;
                if (token.size() > 1) {
                    
                    try { l = stoi(token.substr(1)); }
                    catch (...) { finish(_pe, "Invalid integer format after '?'"); }
                    if (!(cin >> r)) finish(_pe, "Expected r after ?l");
                } else {
                    
                    if (!(cin >> l >> r)) finish(_pe, "Expected l r after '?'");
                }
            } else {
                
                is_query = true;
                try { l = stoi(token); }
                catch (...) { finish(_pe, "Expected '?', '!', or integer start of query"); }
                if (!(cin >> r)) finish(_pe, "Expected r after l");
            }

            if (is_ans) {
                if (x == ans) {
                    
                    break;
                } else {
                    
                    
                    
                    cout << -1 << endl;
                    finish(_wa, format("Wrong answer. Expected %d, got %d", ans, x));
                }
            } else if (is_query) {
                current_case_queries++;
                if (current_case_queries > queries) {
                    queries = current_case_queries;
                }
                
                
                if (current_case_queries % 5 == 0) log_metrics();

                if (current_case_queries > 15) {
                    cout << -1 << endl;
                    finish(_wa, "Query limit exceeded (15 per test case)");
                }

                if (l < 1 || r > n || l > r) {
                    cout << -1 << endl;
                    finish(_wa, format("Invalid query range [%d, %d] for n=%d", l, r, n));
                }

                
                vector<int> res;
                res.reserve(r - l + 1);
                for (int k = l; k <= r; ++k) {
                    res.push_back(a[k]);
                }
                sort(res.begin(), res.end());

                for (size_t k = 0; k < res.size(); ++k) {
                    cout << res[k] << (k == res.size() - 1 ? "" : " ");
                }
                cout << endl;
            }
        }
    }

    finish(_ok, "All test cases passed");
    return 0;
}


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


static long long total_queries = 0;
static long long total_limit = 0;


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


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


void solve_test_case() {
    
    
    int n = inf.readInt();
    int target = inf.readInt();
    
    
    cout << n << endl;
    
    
    
    
    vector<int> p(n + 1);
    p[target] = target;
    
    vector<int> others;
    others.reserve(n);
    for (int i = 1; i <= n; ++i) {
        if (i != target) others.push_back(i);
    }
    
    
    
    shuffle(others.begin(), others.end());
    
    for (size_t i = 0; i < others.size(); i += 2) {
        int u = others[i];
        int v = others[i+1];
        p[u] = v;
        p[v] = u;
    }
    
    
    int queries_case = 0;
    const int LIMIT_PER_CASE = 15;
    
    while (true) {
        string type;
        
        if (!(cin >> type)) {
            finish(_pe, "Unexpected EOF or error reading query type");
        }
        
        if (type == "!") {
            
            int ans;
            if (!(cin >> ans)) {
                finish(_pe, "Unexpected EOF reading answer");
            }
            
            if (ans == target) {
                
                return;
            } else {
                
                cout << -1 << endl;
                finish(_wa, format("Wrong answer: expected %d, got %d", target, ans));
            }
        } else if (type == "?") {
            
            int l, r;
            if (!(cin >> l >> r)) {
                finish(_pe, "Unexpected EOF reading query range");
            }
            
            
            if (l < 1 || r > n || l > r) {
                cout << -1 << endl;
                finish(_wa, format("Invalid query range [%d, %d] for n=%d", l, r, n));
            }
            
            
            queries_case++;
            total_queries++;
            
            
            if (total_queries % 10 == 0) log_metrics();

            
            if (queries_case > LIMIT_PER_CASE) {
                cout << -1 << endl;
                
                finish(_wa, format("Query limit exceeded for test case (used %d > %d)", queries_case, LIMIT_PER_CASE));
            }
            
            
            vector<int> res;
            res.reserve(r - l + 1);
            for (int i = l; i <= r; ++i) {
                res.push_back(p[i]);
            }
            sort(res.begin(), res.end());
            
            
            for (size_t i = 0; i < res.size(); ++i) {
                cout << res[i] << (i == res.size() - 1 ? "" : " ");
            }
            cout << endl;
        } else {
            
            cout << -1 << endl;
            finish(_pe, format("Unknown query type '%s'", type.c_str()));
        }
    }
}

int main(int argc, char* argv[]) {
    registerInteraction(argc, argv);
    
    
    atexit(log_metrics);
    
    
    int t = inf.readInt();
    
    
    total_limit = t * 15LL;
    log_metrics(); 
    
    
    cout << t << endl;
    
    
    for (int i = 0; i < t; ++i) {
        solve_test_case();
    }
    
    finish(_ok, "All test cases passed");
}


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");
    
    
    
    int seed_val = atoi(argv[1]);

    const int MAX_SUM_N = 10000;
    
    struct TestCase {
        int n;
        int fixed_idx;
    };
    vector<TestCase> tests;

    if (seed_val == 1) {
        
        
        for (int i = 1; i <= 3; ++i) {
            tests.push_back({3, i});
        }
        
        tests.push_back({5, rnd.next(1, 5)});
    } else if (seed_val == 2) {
        
        int n = 9999; 
        tests.push_back({n, rnd.next(1, n)});
    } else if (seed_val == 3) {
        
        int n1 = 4999;
        tests.push_back({n1, rnd.next(1, n1)});
        int n2 = 4999;
        tests.push_back({n2, rnd.next(1, n2)});
    } else {
        
        int current_sum = 0;
        while (current_sum < MAX_SUM_N) {
            int rem = MAX_SUM_N - current_sum;
            
            if (rem < 3) break;
            
            int n;
            
            if (rnd.next(5) == 0) {
                int upper = min(rem, 21);
                if (upper < 3) upper = 3;
                n = rnd.next(3, upper);
            } else {
                n = rnd.next(3, rem);
            }
            
            
            if (n % 2 == 0) n--;
            
            
            if (n < 3) n = 3;
            
            
            
            if (current_sum + n > MAX_SUM_N) {
                n = rem;
                if (n % 2 == 0) n--;
                if (n < 3) break;
            }
            
            tests.push_back({n, rnd.next(1, n)});
            current_sum += n;
        }
    }
    
    
    cout << tests.size() << endl;
    
    for (const auto& t : tests) {
        if (mode == "non") {
            
            
            
            
            
            vector<int> p(t.n + 1);
            vector<int> others;
            others.reserve(t.n - 1);
            
            
            p[t.fixed_idx] = t.fixed_idx;
            
            
            for (int i = 1; i <= t.n; ++i) {
                if (i != t.fixed_idx) {
                    others.push_back(i);
                }
            }
            
            
            shuffle(others.begin(), others.end());
            
            for (size_t k = 0; k < others.size(); k += 2) {
                int u = others[k];
                int v = others[k+1];
                p[u] = v;
                p[v] = u;
            }
            
            
            cout << t.n << endl;
            for (int i = 1; i <= t.n; ++i) {
                cout << p[i] << (i == t.n ? "" : " ");
            }
            cout << endl;
            
        } else {
            
            
            
            cout << t.n << " " << t.fixed_idx << endl;
        }
    }

    return 0;
}