Submission #1366325

#TimeUsernameProblemLanguageResultExecution timeMemory
1366325opeleklanosToy Design (EGOI22_toydesign)C++20
100 / 100
4 ms432 KiB
#include <iostream>
#include <vector>
using namespace std;

// #include "ToyDesign.h"


// vector<vector<int>> secret_ans;

// vector<vector<vector<int>>> levels;

// int Connected(int lvl, int a, int b){
//     int x=-1, y=-1;
//     for(int i = 0; i<levels[lvl].size(); i++){
//         int count = 0;
//         for(auto j:levels[lvl][i]) if(j == a || j==b) count++;
//         if(count == 0) continue;
//         if(count == 2) return lvl;
//         if(count == 1){
//             if(x == -1) x = i;
//             else y = i;
//         }
//     }

//     levels.push_back(levels[lvl]);
//     for(auto i : levels.back()[y]) levels.back()[x].push_back(i);
//     levels.back()[y].assign(0, 0);
//     return levels.size()-1;
// }

// -----------------------------------------------------------------------------------


int Connected(int lvl, int a, int b){
    cout<<"? "<<lvl<<' '<<a<<' '<<b<<endl;
    int ans; cin>>ans;
    return ans;
}

int lastLevel = 0;
vector<int> rep;


struct segTree{
    int l; int r;
    int leader;
    segTree * lc, * rc;
    int level;
    segTree(int ind){
        leader = rep[ind];
        l = r = ind;
        level = 0;
        lc = rc = nullptr;
    }

    segTree(segTree*le, segTree*ri, int stLevel){
        lc = le;
        rc = ri;
        l = lc->l;
        r = rc->r;
        leader = lc->leader;
        if(stLevel == -1) stLevel = rc->level;
        level = Connected(stLevel, lc->leader, rc->leader);
        lastLevel++;
    }
};

segTree * build(int l, int r, int leftLevel){
    int mid = (l+r)/2;
    if(l==r) return new segTree(l);

    segTree * le = build(l, mid, leftLevel);
    segTree * ri = build(mid+1, r, le->level);

    return new segTree(le, ri, ((lastLevel == rep.size()-1)?0 : lastLevel));

    // else return new segTree(build(l, mid), build(mid+1, r));
}

int query(segTree * st, int nd){
    if(st->l == st->r) return st->leader;

    if(st->lc->level == Connected(st->lc->level, nd, st->lc->leader)) return query(st->lc, nd);
    else return query(st->rc, nd);
}

void ToyDesign(int n, int max_ops){
    rep.clear();
    rep.push_back(1);
    for(int i = 2; i<=n; i++){
        int b = Connected(lastLevel, 1, i);
        if(b>lastLevel) rep.push_back(i);
        lastLevel = b;
    }

    segTree * seg = build(0, rep.size()-1, -1);

    vector<pair<int, int>> ans;

    int repind = 0;

    for(int i = 1; i<=n; i++){
        if(i == rep[repind]){
            repind++;
            continue;
        }
        ans.push_back({i, query(seg, i)});
    }
    cout<<"! "<<ans.size()<<endl;
    for(auto i : ans) cout<<i.first<<' '<<i.second<<endl;
}

// int main(void){
//     freopen("input.txt", "r", stdin);
//     int n1, m1; cin>>n1>>m1;

//     secret_ans.assign(m1, {});

//     for(int i = 0; i<n1; i++){
//         int a, b; cin>>a>>b;
//         secret_ans[a].push_back(b);
//     }

//     levels.push_back(secret_ans);

//     ToyDesign(n1, 10000);
// }

int main(void){
    int n, maxq;
    cin>>n;

    ToyDesign(n, 0);

    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...