Submission #1353777

#TimeUsernameProblemLanguageResultExecution timeMemory
1353777AvianshTower (BOI25_tow)C++20
0 / 100
17 ms1136 KiB
#include <bits/stdc++.h>

using namespace std;

mt19937 rng(1234);

map<array<int,3>,set<array<int,2>>>mem;

set<array<int,2>> query(int x, int y, int z){
    vector<int>arr(3);
    arr[0]=x;
    arr[1]=y;
    arr[2]=z;
    sort(arr.begin(),arr.end());
    x=arr[0];
    y=arr[1];
    z=arr[2];
    if(mem.find({x,y,z})!=mem.end()){
        return mem[{x,y,z}];
    }
    cout << "? " << x << " " << y << " " << z << endl;
    int r;
    cin >> r;
    set<array<int,2>>ans;
    for(int i = 0;i<r;i++){
        int a,b;
        cin >> a;
        cin >> b;
        ans.insert({min(a,b),max(a,b)});
    }
    mem[{x,y,z}]=ans;
    return mem[{x,y,z}];
}

void bin(vector<int>&arr){
    int n = arr.size();
    if(n<=2){
        return;
    }
    vector<int>left,right;
    set<int>parted;
    int x = arr[(int)(rng()%n)];
    parted.insert(x);
    left.push_back(x);
    int y = arr[(int)(rng()%n)];
    while(y==x){
        y = arr[(int)(rng()%n)];
    }
    parted.insert(y);
    right.push_back(y);
    while(parted.size()!=n){
        int z = arr[(int)(rng()%n)];
        while(parted.find(z)!=parted.end()){
            z = arr[(int)(rng()%n)];
        }
        set<array<int,2>>q = query(x,y,z);
        if(q.find({min(x,z),max(x,z)})!=q.end()){
            ///this one exists so put in left
            parted.insert(z);
            left.push_back(z);
        }
        else if(q.find({min(y,z),max(y,z)})!=q.end()){
            ///it exists in right
            parted.insert(z);
            right.push_back(z);
        }
        else{
            ///huh must restart
            while(parted.size()){
                parted.erase(parted.begin());
            }
            while(left.size()){
                left.pop_back();
            }
            while(right.size()){
                right.pop_back();
            }
            ///lets take x,z as it bigger
            y=z;
            parted.insert(x);
            left.push_back(x);
            parted.insert(y);
            right.push_back(y);
        }
    }
    ///partition successful
    if(left.size()<right.size()){
        swap(left,right);
    }
    bin(left);
    bin(right);
    set<array<int,2>>q=query(left[left.size()-1],left[0],right[0]);
    if(q.find({min(left[0],right[0]),max(left[0],right[0])})!=q.end()){
        reverse(left.begin(),left.end());
    }
    if(right.size()!=1){
        q=query(right[right.size()-1],right[0],left[0]);
        if(q.find({min(left[left.size()-1],right[right.size()-1]),max(left[left.size()-1],right[right.size()-1])})!=q.end()){
            reverse(right.begin(),right.end());
        }
    }
    for(int i = 0;i<left.size();i++){
        arr[i]=left[i];
    }
    for(int i = left.size();i<n;i++){
        arr[i]=right[i-left.size()];
    }
}

void solve(){
    while(mem.size()){
        mem.erase(mem.begin());
    }
    int n;
    cin >> n;
    vector<int>arr(n);
    iota(arr.begin(),arr.end(),0);
    bin(arr);
    cout << "! ";
    for(int i : arr){
        cout << i << " ";
    }
    cout << endl;
}

signed main(){
    int t,k;
    cin >> t >> k;
    while(t--){
        solve();
    }
    return 0;
}
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...