Submission #428650

#TimeUsernameProblemLanguageResultExecution timeMemory
428650lycPark (JOI17_park)C++14
77 / 100
263 ms672 KiB
#include "park.h"

#include <bits/stdc++.h>
using namespace std;

#define TRACE(x) cerr << #x << " :: " << x << endl
#define _ << " " <<
#define SZ(x) ((int)(x).size())
#define ALL(x) (x).begin(),(x).end()
#define FOR(i,a,b) for(int i=(a);i<=(b);++i)
#define RFOR(i,a,b) for(int i=(a);i>=(b);--i)

static int Place[1400];

const int mxN = 1405;
vector<int> ans, rem, al[mxN], preorder, path;
int pa[mxN], solved[mxN];

void myans(int i, int j) {
    if (i > j) swap(i,j);
    al[i].push_back(j);
    al[j].push_back(i);
    Answer(i,j);
}

bool myask(int i, int j, vector<int> v) {
    if (i > j) swap(i,j);
    v.push_back(i);
    v.push_back(j);

    for (int& x : v) Place[x] = 1;
    int ret = Ask(i,j,Place);
    for (int& x : v) Place[x] = 0;
    return ret;
}

void solveLine() {
    int l = path[0];
    while (true) {
        int it = SZ(path);
        FOR(i,0,SZ(path)-1) if (path[i] == l) { it = i+1; break; }

        int u;
        if (it < SZ(path)) u = path[it];
        else break;

        while (true) {
            //TRACE("CHECK" _ l _ u);
            if (myask(l,u,{})) {
                //TRACE("ANSWER" _ l _ u);
                myans(l,u);
                l = u;
                break;
            }

            int lo = -1, hi = SZ(rem);
            while (hi-lo > 1) {
                int mid = (lo+hi)/2;

                vector<int> v2;
                FOR(i,0,mid) v2.push_back(rem[i]);
                if (myask(l,u,v2)) hi = mid;
                else lo = mid;
            }
            u = rem[hi];

            rem.erase(find(ALL(rem),u));
            FOR(i,0,SZ(path)-1) if (path[i] == l) {
                path.insert(path.begin()+i+1, u);
                break;
            }
        }
    }
    //cerr << "path: "; for (int& x : path) { cerr << x << ' '; } cerr << endl;
    //cerr << "rem: "; for (int& x : rem) { cerr << x << ' '; } cerr << endl;
}

void dfs(int u, int p) {
    preorder.push_back(u);
    pa[u] = -1;
    solved[u] = 1;
    for (int& v : al[u]) if (v != p) {
        dfs(v,u);
    }
}

void Detect(int T, int N) {
    if (T == 1) {
        FOR(i,0,N-1){
            FOR(j,i+1,N-1){
                Place[i] = Place[j] = 1;
                if (Ask(i,j,Place)) Answer(i,j);
                Place[i] = Place[j] = 0;
            }
        }
    } else {
        path.push_back(0);
        path.push_back(N-1);

        FOR(i,1,N-2) rem.push_back(i);

        solveLine();
        while (SZ(rem)) {
            int u = rem.back(); rem.pop_back();

            preorder.clear();
            dfs(0,-1);
            //cerr << "preorder: "; for (int& x : preorder) { cerr << x << ' '; } cerr << endl;

            int lo = -1, hi = SZ(preorder);
            while (hi-lo > 1) {
                int mid = (lo+hi)/2;

                vector<int> v2;
                FOR(i,0,mid) v2.push_back(preorder[i]);
                FOR(i,0,N-1) if (!solved[i]) v2.push_back(i);
                if (myask(0,u,v2)) hi = mid;
                else lo = mid;
            }
            int rt = preorder[hi];
            //TRACE((hi < SZ(preorder)) _ rt _ u);

            path.clear();
            path.push_back(rt);
            path.push_back(u);
            solveLine();
        }
    }
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...