Problem: cf1526_f
Difficulty: medium
Categories: math
Time limit: 6000 ms, memory limit: 256 MB

This is an interactive problem.

There is a secret permutation $p$ ($1$-indexed) of numbers from $1$ to $n$. More formally, for $1 \leq i \leq n$, $1 \leq p[i] \leq n$ and for $1 \leq i < j \leq n$, $p[i] \neq p[j]$. It is known that $p[1]<p[2]$.

In $1$ query, you give $3$ distinct integers $a,b,c$ ($1 \leq a,b,c \leq n$), and receive the median of $\{|p[a]-p[b]|,|p[b]-p[c]|,|p[a]-p[c]|\}$.

In this case, the median is the $2$-nd element ($1$-indexed) of the sequence when sorted in non-decreasing order. The median of $\{4,6,2\}$ is $4$ and the median of $\{0,123,33\}$ is $33$.

Can you find the secret permutation in not more than $2n+420$ queries?

Note: the grader is not adaptive: the permutation is fixed before any queries are made.

Input

The first line of input contains a single integer $t$ $(1 \leq t \leq 1000)$ — the number of testcases.

The first line of each testcase consists of a single integer $n$ $(20 \leq n \leq 100000)$ — the length of the secret permutation.

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

Interaction

For each testcase, you begin the interaction by reading $n$.

To perform a query, output "? a b c" where $a,b,c$ is the $3$ indices you want to use for the query.

Numbers have to satisfy $1 \leq a,b,c \leq n$ and $a \neq b$,$b \neq c$,$a \neq c$.

For each query, you will receive a single integer $x$: the median of $\{|p[a]-p[b]|,|p[b]-p[c]|,|p[a]-p[c]|\}$.

In case your query is invalid or you asked more than $2n+420$ queries, the interactor will print "−1" and will finish interaction. You will receive Wrong answer verdict. Make sure to exit immediately to avoid getting other verdicts.

When you have determined the secret permutation, output "! p[1] p[2] ... p[n]". If the secret permutation is correct, the interactor will print "1". Otherwise, the interactor will print "-1" and will finish interaction. You will receive Wrong answer verdict. Make sure to exit immediately to avoid getting other verdicts.

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

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

```
1
20

6

9

1
```

Output

```
? 1 5 2

? 20 19 2

! 9 10 19 7 16 18 11 14 15 6 20 8 17 4 5 3 12 2 13 1
```

Note

The secret permutation is $\{9,10,19,7,16,18,11,14,15,6,20,8,17,4,5,3,12,2,13,1\}$.

For the first query, the values of $(a,b,c)$ is $(1,5,2)$. Since $p[1]=9$, $p[5]=16$ and $p[2]=10$. The return value is the median of $\{|9-16|,|16-10|,|9-10|\}$ which is $6$.

For the second query, the values of $(a,b,c)$ is $(20,19,2)$. Since $p[20]=1$, $p[19]=13$ and $p[2]=10$. The return value is the median of $\{|1-13|,|13-10|,|1-10|\}$ which is $9$.

By some miracle, we have figured out that the secret permutation is $\{9,10,19,7,16,18,11,14,15,6,20,8,17,4,5,3,12,2,13,1\}$. We output it and receive $1$ from the interactor, meaning that we have guessed the secret permutation correctly.

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 << "\n";
        tout << "query_limit=" << query_limit << "\n";
        tout.flush();
    } catch (...) {
        
    }
}

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

static int median3(int a, int b, int c) {
    array<int, 3> v{a, b, c};
    sort(v.begin(), v.end());
    return v[1];
}

static void sendMinusOne() {
    cout << -1 << "\n";
    cout.flush();
}

int main(int argc, char** argv) {
    registerInteraction(argc, argv);
    atexit(log_metrics);

    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int t = inf.readInt(1, 1000, "t");
    vector<int> ns(t);
    vector<vector<int>> perms(t); 

    long long sumN = 0;
    for (int tc = 0; tc < t; tc++) {
        int n = inf.readInt(20, 100000, "n");
        ns[tc] = n;
        sumN += n;

        vector<int> p(n + 1, 0);
        vector<int> seen(n + 1, 0);
        for (int i = 1; i <= n; i++) {
            int v = inf.readInt(1, n, "p[i]");
            p[i] = v;
            if (++seen[v] != 1) finish(_fail, "Invalid hidden permutation: duplicates");
        }
        if (!(p[1] < p[2])) finish(_fail, "Invalid hidden permutation: expected p[1] < p[2]");
        perms[tc] = std::move(p);

        query_limit += 2LL * n + 420;
    }
    if (sumN > 100000) finish(_fail, "Invalid hidden input: sum(n) exceeds 100000");

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

    
    log_metrics();

    cout << t << "\n";
    cout.flush();

    for (int tc = 0; tc < t; tc++) {
        const int n = ns[tc];
        const vector<int>& p = perms[tc];

        const long long per_case_limit = 2LL * n + 420;
        long long used = 0;

        cout << n << "\n";
        cout.flush();

        while (true) {
            string op;
            if (!(cin >> op)) finish(_pe, "Unexpected EOF from contestant");

            if (!op.empty() && op[0] == '?') {
                long long a_ll, b_ll, c_ll;
                if (!(cin >> a_ll >> b_ll >> c_ll)) {
                    sendMinusOne();
                    finish(_pe, "Malformed query (expected '? a b c')");
                }

                queries++;
                used++;
                if (queries > hard_cap) finish(_pe, "Hard cap exceeded (possible infinite loop)");
                if (used > per_case_limit) {
                    sendMinusOne();
                    finish(_wa, "Query limit exceeded");
                }

                if (!(1 <= a_ll && a_ll <= n && 1 <= b_ll && b_ll <= n && 1 <= c_ll && c_ll <= n)) {
                    sendMinusOne();
                    finish(_wa, "Query index out of range");
                }
                int a = (int)a_ll, b = (int)b_ll, c = (int)c_ll;
                if (a == b || b == c || a == c) {
                    sendMinusOne();
                    finish(_wa, "Query indices not distinct");
                }

                int d1 = abs(p[a] - p[b]);
                int d2 = abs(p[b] - p[c]);
                int d3 = abs(p[a] - p[c]);
                int ans = median3(d1, d2, d3);

                cout << ans << "\n";
                cout.flush();
            } else if (!op.empty() && op[0] == '!') {
                vector<int> guess(n + 1, 0);
                vector<int> seen(n + 1, 0);
                for (int i = 1; i <= n; i++) {
                    long long v_ll;
                    if (!(cin >> v_ll)) {
                        sendMinusOne();
                        finish(_pe, "Malformed final answer (not enough integers)");
                    }
                    if (v_ll < 1 || v_ll > n) {
                        sendMinusOne();
                        finish(_wa, "Final answer contains out-of-range value");
                    }
                    int v = (int)v_ll;
                    guess[i] = v;
                    if (++seen[v] != 1) {
                        sendMinusOne();
                        finish(_wa, "Final answer is not a permutation");
                    }
                }

                bool ok = true;
                for (int i = 1; i <= n; i++) {
                    if (guess[i] != p[i]) {
                        ok = false;
                        break;
                    }
                }
                if (!ok) {
                    sendMinusOne();
                    finish(_wa, "Wrong permutation");
                }

                cout << 1 << "\n";
                cout.flush();
                if (tc == t - 1) finish(_ok, "OK");
                break;
            } else {
                sendMinusOne();
                finish(_pe, "Unknown operation token (expected '?' or '!')");
            }
        }
    }

    finish(_pe, "Contestant did not terminate properly after all testcases");
    return 0;
}


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 << "\n";
        tout << "query_limit=" << query_limit << "\n";
        tout.flush();
    } catch (...) {
        
    }
}

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

static uint64_t fnv1a64(const string& s) {
    uint64_t h = 14695981039346656037ULL;
    for (unsigned char c : s) {
        h ^= (uint64_t)c;
        h *= 1099511628211ULL;
    }
    return h;
}

static uint64_t splitmix64(uint64_t& x) {
    uint64_t z = (x += 0x9e3779b97f4a7c15ULL);
    z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9ULL;
    z = (z ^ (z >> 27)) * 0x94d049bb133111ebULL;
    return z ^ (z >> 31);
}

static vector<int> genPermutation(int n, uint64_t seed) {
    vector<int> p(n + 1, 0);
    for (int i = 1; i <= n; i++) p[i] = i;

    uint64_t x = seed;
    for (int i = n; i >= 2; --i) {
        int j = (int)(splitmix64(x) % (uint64_t)i) + 1; 
        swap(p[i], p[j]);
    }
    if (p[1] > p[2]) swap(p[1], p[2]);
    return p;
}

static int median3(int a, int b, int c) {
    array<int, 3> v{a, b, c};
    sort(v.begin(), v.end());
    return v[1];
}

static void sendMinusOne() {
    cout << -1 << "\n";
    cout.flush();
}

int main(int argc, char** argv) {
    registerInteraction(argc, argv);
    atexit(log_metrics);
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    uint64_t base_seed = fnv1a64((argc >= 2) ? string(argv[1]) : string("cf1526F"));

    int t = inf.readInt(1, 1000, "t");
    vector<int> ns(t);
    long long sumN = 0;
    for (int tc = 0; tc < t; tc++) {
        int n = inf.readInt(20, 100000, "n");
        ns[tc] = n;
        sumN += n;
        query_limit += 2LL * n + 420;
    }
    if (sumN > 100000) finish(_fail, "Invalid hidden input: sum(n) exceeds 100000");
    if (!inf.seekEof()) finish(_fail, "Unexpected extra tokens in adaptive input");

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

    log_metrics(); 

    cout << t << "\n";
    cout.flush();

    for (int tc = 0; tc < t; tc++) {
        const int n = ns[tc];
        const long long per_case_limit = 2LL * n + 420;
        long long used = 0;

        uint64_t seed = base_seed ^ (uint64_t)n ^ (uint64_t)(tc + 1) * 0x9e3779b97f4a7c15ULL;
        vector<int> p = genPermutation(n, seed);

        cout << n << "\n";
        cout.flush();

        while (true) {
            string op;
            if (!(cin >> op)) finish(_pe, "Unexpected EOF from contestant");

            if (!op.empty() && op[0] == '?') {
                long long a_ll, b_ll, c_ll;
                if (!(cin >> a_ll >> b_ll >> c_ll)) {
                    sendMinusOne();
                    finish(_pe, "Malformed query (expected '? a b c')");
                }

                queries++;
                used++;
                if (queries > hard_cap) finish(_pe, "Hard cap exceeded (possible infinite loop)");
                if (used > per_case_limit) {
                    sendMinusOne();
                    finish(_wa, "Query limit exceeded");
                }

                if (!(1 <= a_ll && a_ll <= n && 1 <= b_ll && b_ll <= n && 1 <= c_ll && c_ll <= n)) {
                    sendMinusOne();
                    finish(_wa, "Query index out of range");
                }
                int a = (int)a_ll, b = (int)b_ll, c = (int)c_ll;
                if (a == b || b == c || a == c) {
                    sendMinusOne();
                    finish(_wa, "Query indices not distinct");
                }

                int d1 = abs(p[a] - p[b]);
                int d2 = abs(p[b] - p[c]);
                int d3 = abs(p[a] - p[c]);
                int ans = median3(d1, d2, d3);

                cout << ans << "\n";
                cout.flush();
            } else if (!op.empty() && op[0] == '!') {
                vector<int> guess(n + 1, 0);
                vector<int> seen(n + 1, 0);
                for (int i = 1; i <= n; i++) {
                    long long v_ll;
                    if (!(cin >> v_ll)) {
                        sendMinusOne();
                        finish(_pe, "Malformed final answer (not enough integers)");
                    }
                    if (v_ll < 1 || v_ll > n) {
                        sendMinusOne();
                        finish(_wa, "Final answer contains out-of-range value");
                    }
                    int v = (int)v_ll;
                    guess[i] = v;
                    if (++seen[v] != 1) {
                        sendMinusOne();
                        finish(_wa, "Final answer is not a permutation");
                    }
                }

                bool ok = true;
                for (int i = 1; i <= n; i++) {
                    if (guess[i] != p[i]) {
                        ok = false;
                        break;
                    }
                }
                if (!ok) {
                    sendMinusOne();
                    finish(_wa, "Wrong permutation");
                }

                cout << 1 << "\n";
                cout.flush();
                if (tc == t - 1) finish(_ok, "OK");
                break;
            } else {
                sendMinusOne();
                finish(_pe, "Unknown operation token (expected '?' or '!')");
            }
        }
    }

    finish(_pe, "Contestant did not terminate properly after all testcases");
    return 0;
}


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

static long long gcdll(long long a, long long b) {
    while (b) { long long t = a % b; a = b; b = t; }
    return a;
}

static vector<int> perm_seed1_n20() {
    int n = 20;
    vector<int> p;
    p.reserve(n);
    
    
    p.push_back(1);
    p.push_back(2);
    int lo = 3, hi = n;
    bool takeHi = true;
    while ((int)p.size() < n) {
        if (takeHi) p.push_back(hi--);
        else p.push_back(lo++);
        takeHi = !takeHi;
    }
    if (p[0] > p[1]) swap(p[0], p[1]);
    return p;
}

static vector<int> perm_seed2_rev(int n) {
    
    
    vector<int> p;
    p.reserve(n);
    p.push_back(n - 1);
    p.push_back(n);
    for (int x = n - 2; x >= 1; --x) p.push_back(x);
    if ((int)p.size() != n) abort();
    if (p[0] > p[1]) swap(p[0], p[1]);
    return p;
}

static vector<int> perm_affine(int n) {
    
    long long a;
    do {
        a = rnd.next(1, n - 1);
    } while (gcdll(a, n) != 1);
    long long b = rnd.next(0, n - 1);

    vector<int> p(n);
    for (int i = 0; i < n; i++) {
        long long v = (a * i + b) % n;
        p[i] = (int)v + 1;
    }
    if (p[0] > p[1]) swap(p[0], p[1]);
    return p;
}

static vector<int> perm_blocky(int n) {
    vector<int> base(n);
    iota(base.begin(), base.end(), 1);

    
    vector<pair<int,int>> blocks;
    for (int i = 0; i < n; ) {
        int rem = n - i;
        int len;
        if (rem <= 5000) len = rem;
        else len = rnd.next(200, 4000);
        blocks.push_back({i, i + len});
        i += len;
    }

    
    for (int i = 0; i + 1 < (int)blocks.size(); i++) {
        int j = rnd.next(i, min<int>((int)blocks.size() - 1, i + 5));
        swap(blocks[i], blocks[j]);
    }

    vector<int> p;
    p.reserve(n);
    for (auto [l, r] : blocks) {
        bool rev = rnd.next(0, 99) < 65;
        if (!rev) {
            for (int i = l; i < r; i++) p.push_back(base[i]);
        } else {
            for (int i = r - 1; i >= l; i--) p.push_back(base[i]);
        }
    }

    
    int K = min(n, rnd.next(2000, 8000));
    deque<int> dq;
    for (int i = 0; i < K; i++) dq.push_back(p[i]);
    vector<int> pref;
    pref.reserve(K);
    bool takeBack = true;
    while (!dq.empty()) {
        int run = rnd.next(1, 7);
        while (run-- && !dq.empty()) {
            if (takeBack) { pref.push_back(dq.back()); dq.pop_back(); }
            else { pref.push_back(dq.front()); dq.pop_front(); }
        }
        takeBack = !takeBack;
    }
    for (int i = 0; i < K; i++) p[i] = pref[i];

    if (p[0] > p[1]) swap(p[0], p[1]);
    return p;
}

static vector<int> perm_ends_runs(int n) {
    deque<int> dq;
    for (int i = 1; i <= n; i++) dq.push_back(i);

    vector<int> p;
    p.reserve(n);

    
    if (n >= 2) {
        p.push_back(n - 1);
        dq.pop_back(); 
        dq.pop_back(); 
        p.push_back(n);
    }

    bool takeFront = true;
    while (!dq.empty()) {
        int run = rnd.next(1, 32);
        while (run-- && !dq.empty()) {
            if (takeFront) { p.push_back(dq.front()); dq.pop_front(); }
            else { p.push_back(dq.back()); dq.pop_back(); }
        }
        takeFront = !takeFront;
    }

    if ((int)p.size() != n) abort();
    if (p[0] > p[1]) swap(p[0], p[1]);
    return p;
}

static vector<int> perm_random(int n) {
    vector<int> p(n);
    iota(p.begin(), p.end(), 1);
    for (int i = n - 1; i >= 1; --i) {
        int j = rnd.next(0, i);
        swap(p[i], p[j]);
    }
    if (p[0] > p[1]) swap(p[0], p[1]);
    return p;
}

static vector<int> generatePermutation(long long seedArg, int n) {
    if (seedArg == 1) return perm_seed1_n20();
    if (seedArg == 2) return perm_seed2_rev(n);
    if (seedArg == 3) {
        
        
        return perm_affine(n);
    }

    int type = rnd.next(0, 3);
    if (type == 0) return perm_ends_runs(n);
    if (type == 1) return perm_blocky(n);
    if (type == 2) {
        
        vector<int> p = perm_affine(n);
        int ops = rnd.next(8, 20);
        for (int it = 0; it < ops; it++) {
            int l = rnd.next(0, n - 1);
            int r = rnd.next(0, n - 1);
            if (l > r) swap(l, r);
            if (r - l >= 2) reverse(p.begin() + l, p.begin() + r + 1);
        }
        if (p[0] > p[1]) swap(p[0], p[1]);
        return p;
    }
    return perm_random(n);
}

static void printPermutation(const vector<int>& p) {
    for (int i = 0; i < (int)p.size(); i++) {
        if (i) cout << ' ';
        cout << p[i];
    }
    cout << "\n";
}

int main(int argc, char** argv) {
    registerGen(argc, argv, 1);
    string mode = opt<string>("mode", "non");

    long long seedArg = 1;
    if (argc >= 2) {
        
        seedArg = atoll(argv[1]);
        if (seedArg <= 0) seedArg = 1;
    }

    int nOpt = opt<int>("n", -1);
    int n;
    if (seedArg == 1) n = 20;
    else if (seedArg == 3) n = 99991; 
    else n = 100000;

    if (seedArg > 3 && nOpt != -1) n = nOpt;
    n = max(20, min(100000, n));

    cout << 1 << "\n";
    cout << n << "\n";

    if (mode == "non") {
        vector<int> p = generatePermutation(seedArg, n);

        
        vector<int> seen(n + 1, 0);
        for (int x : p) {
            if (x < 1 || x > n) abort();
            seen[x]++;
        }
        for (int v = 1; v <= n; v++) if (seen[v] != 1) abort();
        if (!(p[0] < p[1])) abort();

        printPermutation(p);
    } else if (mode == "adp") {
        
        
    } else {
        
        vector<int> p = generatePermutation(seedArg, n);
        if (p[0] > p[1]) swap(p[0], p[1]);
        printPermutation(p);
    }

    return 0;
}