Problem: arc154_d
Difficulty: medium
Categories: data structures
Time limit: 2000 ms, memory limit: 256 MB

### Problem Statement

PCT has a permutation $(P_1,P_2,\dots,P_N)$ of $(1,2,\dots,N)$. You are only informed of $N$.

You can ask him at most $25000$ questions of the following form.

* Specify a triple of integers $(i,j,k)$ such that $1 \le i,j,k \le N$ and ask whether $P_i + P_j > P_k$.

Find all of $P_1,P_2,\dots,P_N$.

### Constraints

* $1 \le N \le 2000$
* $P$ is decided before the start of the interaction of your program and the judge.

### Input and Output

**This is an interactive task**, where your program and the judge interact via input and output.

First, your program is given $N$, the length of the permutation, from Standard Input:

```
$N$
```

Then, you get to ask questions.
Print your question to Standard Output in the following format: (There should be a newline at the end.)

```
? $i$ $j$ $k$
```

If the question is valid, the answer $ans$ will be given from Standard Input:

```
$ans$
```

Here, $ans$ is `Yes` or `No`.

If the question is malformed or judged invalid because you have asked more questions than allowed, `-1` will be given from Standard Input:

```
-1
```

Here, the submission has already been judged incorrect. The judge will end the interaction at this point; preferably, your program should also quit.

Once you have identified all of $P_1, P_2, \dots, P_N$, print them to Standard Output in the following format: (There should be a newline at the end.)

```
! $P_1$ $P_2$ $\dots$ $P_N$
```

### Judging

* **Each time you print something, end it with a newline and flush Standard Output. Otherwise, you might get a TLE verdict.**
* After printing the answer (or receiving `-1`), immediately terminate the program normally. Otherwise, the verdict will be indeterminate.
* Note that unnecessary newlines will be considered as malformed output.

### Sample Interaction

Below is an interaction with $N = 4$ and $P=(3,1,2,4)$.

| Input | Output | Description |
| --- | --- | --- |
| `4` |  | $N$ is given. |
|  | `?` `1` `2` `3` | As the first question, you ask whether $P_1 + P_2 > P_3$. |
| `Yes` |  | We have $P_1 + P_2=4$ and $P_3=2$, so the answer is `Yes`. |
|
|  | `?` `2` `3` `3` | As the second question, you ask whether $P_2 + P_3 > P_3$. |
| `Yes` |  | We have $P_2 + P_3=3$ and $P_3=2$, so the answer is `Yes`. |
|
|  | `?` `2` `3` `4` | As the third question, you ask whether $P_2 + P_3 > P_4$. |
| `No` |  | We have $P_2 + P_3=3$ and $P_4=4$, so the answer is `No`. |
|
|  | `!` `3` `1` `2` `4` | You print $P_1,P_2,P_3,P_4$. We do have $P=(3,1,2,4)$, so you get an AC. |
|

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


static long long queries = 0;
static long long query_limit = 25000; 
static const long long HARD_CAP = 250000; 

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 n = inf.readInt(1, 2000, "N");
    vector<int> p(n);
    for (int i = 0; i < n; ++i) {
        p[i] = inf.readInt(1, n, format("P[%d]", i + 1));
    }

    
    {
        vector<int> sorted_p = p;
        sort(sorted_p.begin(), sorted_p.end());
        for (int i = 0; i < n; ++i) {
            if (sorted_p[i] != i + 1) {
                quitf(_fail, "Hidden input is not a valid permutation of 1..N");
            }
        }
    }

    
    cout << n << endl;

    
    string token;
    while (cin >> token) {
        if (token == "!") {
            
            vector<int> guess(n);
            bool read_ok = true;
            for (int i = 0; i < n; ++i) {
                if (!(cin >> guess[i])) {
                    read_ok = false;
                    break;
                }
            }
            if (!read_ok) {
                finish(_pe, "Could not read complete permutation answer after '!'");
            }

            
            if (guess == p) {
                finish(_ok, "Correct permutation");
            } else {
                finish(_wa, "Incorrect permutation");
            }
        } else {
            
            queries++;

            
            if (queries % 100 == 0) {
                log_metrics();
            }

            
            if (queries > HARD_CAP) {
                finish(_pe, "Query limit hard cap exceeded");
            }

            int i, j, k;

            if (token == "?") {
                
                if (!(cin >> i >> j >> k)) {
                    finish(_pe, "Invalid query format (expected 3 ints after ?)");
                }
            } else {
                
                
                try {
                    size_t pos;
                    i = stoi(token, &pos);
                    if (pos != token.size()) {
                        throw invalid_argument("trailing chars");
                    }
                } catch (...) {
                    finish(_pe, format("Expected integer or '?', found '%s'", token.c_str()));
                }
                if (!(cin >> j >> k)) {
                    finish(_pe, "Invalid query format (expected 2 more ints)");
                }
            }

            
            if (i < 1 || i > n || j < 1 || j > n || k < 1 || k > n) {
                finish(_pe, format("Query indices out of bounds: %d %d %d", i, j, k));
            }

            
            long long val_i = p[i - 1];
            long long val_j = p[j - 1];
            long long val_k = p[k - 1];

            if (val_i + val_j > val_k) {
                cout << "Yes" << endl;
            } else {
                cout << "No" << endl;
            }
        }
    }

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


Adaptive interactor (C++):

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 n_arg = opt<int>("n", 0);
    
    
    long long seed = atoll(argv[1]);

    int n;
    if (n_arg > 0) {
        n = n_arg;
    } else {
        
        if (seed == 1) n = 4;           
        else if (seed == 2) n = 2000;   
        else if (seed == 3) n = 2000;   
        else if (seed == 4) n = 2000;   
        else if (seed == 5) n = 2000;   
        else if (seed == 6) n = 1;      
        else if (seed == 7) n = 2;      
        else {
            
            
            n = rnd.wnext(2000, 20) + 1;
        }
    }

    
    if (mode == "adp") {
        cout << n << endl;
        return 0;
    }

    
    vector<int> p;
    if (n_arg > 0) {
        
        p = rnd.perm(n, 1);
    } else {
        
        if (seed == 1 && n == 4) {
            p = {3, 1, 2, 4};
        } else if (seed == 3) {
            
            p.resize(n);
            iota(p.begin(), p.end(), 1);
        } else if (seed == 4) {
            
            p.resize(n);
            iota(p.begin(), p.end(), 1);
            reverse(p.begin(), p.end());
        } else if (seed == 5) {
            
            p.resize(n);
            iota(p.begin(), p.end(), 1);
            rotate(p.begin(), p.begin() + 1, p.end());
        } else {
            
            p = rnd.perm(n, 1);
        }
    }

    
    cout << n << endl;
    for (int i = 0; i < n; i++) {
        cout << p[i] << (i == n - 1 ? "" : " ");
    }
    cout << endl;

    return 0;
}