제출 #1347165

#제출 시각아이디문제언어결과실행 시간메모리
1347165biank즐거운 행로 (APIO20_fun)C++20
66 / 100
93 ms20912 KiB
#include "fun.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 ii = pair<int, int>;
using vii = vector<ii>;
using ll = long long;
using ld = long double;
using vll = vector<ll>;
using vb = vector<bool>;
using pll = pair<ll, ll>;

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

#define pb push_back
#define eb emplace_back
#define ef emplace_front

#define fst first
#define snd second

const int INF = 1e9;

int furthest(int u, vb &used) {
    const int N = sz(used);
    int node = -1;
    int maxi = -1;
    forn(v, N) if (!used[v]) {
        int curr = hoursRequired(u, v);
        if (curr > maxi) {
            maxi = curr;
            node = v;
        }
    }
    return node;
}

vi createFunTour(int N, int Q) {
    if (N <= 500) {
        vb used(N, false);
        vi ret = {furthest(0, used)};
        forn(i, N - 1) {
            used[ret[i]] = true;
            ret.pb(furthest(ret[i], used));
        }
        return ret;
    }
    
    bool flag = true;
    forsn(i, 1, N) flag &= hoursRequired((i - 1) / 2, i) == 1;
    
    vector<vi> adj(N);
    vi par(N);
    vii furthest(N);
    auto dfs = [&](auto dfs, int i, int p) -> void {
        furthest[i] = {0, i}, par[i] = p;
        for (int j : adj[i]) if (j != p) {
            dfs(dfs, j, i);
            ii childBest = furthest[j];
            childBest.fst++;
            furthest[i] = max(furthest[i], childBest);
        }
    };
    
    if (flag) {
        forsn(i, 1, N) adj[(i - 1) / 2].pb(i);
        dfs(dfs, 0, -1);
    } else {
        vi depth(N);
        forn(i, N) depth[i] = hoursRequired(0, i);
        
        
        par[0] = -1;
        vector<tuple<bool, int, int>> st;
        st.eb(false, 0, 0); 
        forsn(i, 1, N) {
            while (true) {
                auto [hasParent, node, dist] = st.back();
                if (dist < depth[i]) break;
                if (dist == depth[i] + 1 && !hasParent) {
                    adj[node].pb(i);
                    adj[i].pb(node);
                }
                st.pop_back();
            }
            auto [hasParent, node, dist] = st.back();
            if (dist == depth[i] - 1) {
                adj[i].pb(node);
                adj[node].pb(i);
                st.eb(true, i, depth[i]);
            } else {
                st.eb(false, i, depth[i]);
            }
        }
        dfs(dfs, get<1>(st.back()), -1);
    }
    
    
    
    vb used(N, false);
    auto find = [&](int x) {
        ii maxi = furthest[x];
        int up = 0;
        while (par[x] != -1) {
            int prev = x;
            x = par[x], up++;
            ii currBest = used[x] ? make_pair(-INF, x) : make_pair(0, x);
            for (int y : adj[x]) if (y != par[x] && y != prev) {
                ii childBest = furthest[y];
                childBest.fst++;
                currBest = max(currBest, childBest);
            }
            currBest.fst += up;
            maxi = max(maxi, currBest);
        }
        return maxi;
    };
    auto deactivate = [&](int i) {
        used[i] = true;
        while (i != -1) {
            if (used[i]) furthest[i] = {-INF, i};
            else furthest[i] = {0, i};
            for (int j : adj[i]) if (j != par[i]) {
                ii childBest = furthest[j];
                childBest.fst++;
                furthest[i] = max(furthest[i], childBest);
            }
            i = par[i];
        }
    };
    vi ret = {find(0).snd};
    forn(i, N - 1) {
        deactivate(ret[i]);
        ret.pb(find(ret[i]).snd);
    }
    return ret;
}
#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...