제출 #1257828

#제출 시각아이디문제언어결과실행 시간메모리
1257828biank이주 (IOI25_migrations)C++20
30 / 100
68 ms1620 KiB
#include "migrations.h"
#include <bits/stdc++.h>

using namespace std;

#define forsn(i, s, n) for (int i = int(s); i < int(n); i++)
#define forn(i, n) forsn(i, 0, n)
#define dforsn(i, s, n) for (int i = int(n) - 1; i >= int(s); i--)
#define dforn(i, n) dforsn(i, 0, n)

using vi = vector<int>;
using ll = long long;
using ii = pair<int, int>;

#define fst first
#define snd second

#define sz(x) int(x.size())
#define all(x) begin(x), end(x)

#define pb push_back
#define eb emplace_back

const int N = 10000;
const int K = 15;

int up[K][N], depth[N];

int lca(int u, int v) {
    if (depth[u] < depth[v]) swap(u, v);
    int diff = depth[u] - depth[v];
    forn(i, K) if (diff >> i & 1) u = up[i][u];
    if (u == v) return u;
    dforn(i, K) if (up[i][u] != up[i][v]) {
        u = up[i][u], v = up[i][v];
    }
    assert(up[0][u] == up[0][v]);
    return up[0][u];
}

int dist(int u, int v) {
    return depth[u] + depth[v] - 2 * depth[lca(u, v)];
}

vi perm[N], invPerm[N];

/*void generate_perms() {
    srand(42);
    vi p(5);
    iota(all(p), 0);
    forn(i, N) {
        random_shuffle(all(p));
        perm[i] = p;
        vi inv_p(5);
        forn(j, 5) inv_p[p[j]] = j;
        invPerm[i] = inv_p;
    }
}*/

int knownU, knownV;
int u, v;
int message;
vi pending;

int getOption() {
    int idx = 0;
    forn(i, sz(pending)) forsn(j, i + 1, sz(pending)) {
        if (pending[i] == u && pending[j] == v) {
            knownU = u, knownV = v;
            return idx;
        }
        idx++;
    }
    forn(i, sz(pending)) {
        if (pending[i] == u && knownV == v) {
            knownU = u;
            return idx;
        }
        idx++;
    }
    forn(i, sz(pending)) {
        if (knownU == u && pending[i] == v) {
            knownV = v;
            return idx;
        }
        idx++;
    }
    assert(knownU == u && knownV == v);
    return idx;
}

int send_message(int /*N*/, int i, int Pi) {
    if (i == 1) {
        //generate_perms();
        depth[0] = 0;
        forn(j, K) up[j][0] = 0; 
        u = 0, v = 0;
        message = 0;
        knownU = 0, knownV = 0;
    }
    pending.pb(i);
    up[0][i] = Pi, depth[i] = depth[Pi] + 1;
    forn(j, K - 1) up[j + 1][i] = up[j][up[j][i]];
    if (dist(i, v) > dist(u, v)) u = i;
    else if (dist(i, u) > dist(u, v)) v = i;
    if (u != knownU && v != knownV && i < N - 4) {
        if (u > v) swap(u, v);
    }
    if (i < N - 17) return 0;
    if (i == N - 1) {
        cerr << u << ' ' << v << '\n';
        vector<ii> candidates = {
            {knownU, N - 1},
            {knownU, N - 2},
            {N - 1, knownV},
            {N - 1, N - 2},
            {knownU, knownV}
        };
        int idx = 0;
        while (candidates[idx] != ii{u, v}) idx++;
        knownU = u, knownV = v;
        return idx;
    }
    if (i == N - 2) {
        vi candidates = {knownU, N - 2, N - 3, N - 4};
        int idx = 0;
        while (candidates[idx] != u) idx++;
        knownU = candidates[idx];
        return idx;
    }
    if (i == N - 5 || i == N - 17) {
        assert(message == 0);
        message = getOption();
        pending.clear();
    }
    int digit = message % 5;
    message /= 5;
    return digit;
}

ii getDiameter(int option, int U, int V) {
    forn(i, sz(pending)) forsn(j, i + 1, sz(pending)) {
        if (option-- == 0) return {pending[i], pending[j]};
    }
    forn(i, sz(pending)) {
        if (option-- == 0) return {pending[i], V};
    }
    forn(i, sz(pending)) {
        if (option-- == 0) return {U, pending[i]};
    }
    assert(option == 0);
    return {U, V};
}

ii longest_path(vi S) {
    int option = 0;
    dforsn(i, N - 17, N - 5) option = 5 * option + S[i];
    pending.clear();
    forsn(i, 1, N - 17 + 1) pending.pb(i);
    int U = 0, V = 0;
    tie(U, V) = getDiameter(option, U, V);
    option = 0;
    pending.clear();
    forsn(i, N - 17 + 1, N - 5 + 1) pending.pb(i);
    dforsn(i, N - 5, N - 2) option = 5 * option + S[i];
    tie(U, V) = getDiameter(option, U, V);
    U = vi{U, N - 2, N - 3, N - 4}[S[N - 2]];
    return vector<ii>{
            {U, N - 1},
            {U, N - 2},
            {N - 1, V},
            {N - 1, N - 2},
            {U, V}
    }[S[N - 1]];
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...