Submission #916053

# Submission time Handle Problem Language Result Execution time Memory
916053 2024-01-25T08:09:57 Z Alcabel Prize (CEOI22_prize) C++17
35 / 100
3500 ms 314264 KB
#pragma GCC optimize("O3", "Ofast")
#include <bits/stdc++.h>
using namespace std;

const int maxn = 1e6;
int par[maxn], sz[maxn];
pair<int, int> minH[maxn];

int getParent(int v) {
    if (par[v] != v) {
        par[v] = getParent(par[v]);
    }
    return par[v];
}

int getMinH(int v) {
    return minH[getParent(v)].second;
}
    
void uniteSets(int v, int u) {
    v = getParent(v), u = getParent(u);
    if (v == u) {
        return;
    }
    if (sz[v] < sz[u]) {
        swap(v, u);
    }
    sz[v] += sz[u];
    par[u] = v;
    minH[v] = min(minH[u], minH[v]);
}

vector<int> g1[maxn], g2[maxn];
int tin1[maxn], tout1[maxn], tin2[maxn], tout2[maxn], tt;

void dfs1(int v) {
    tin1[v] = tt++;
    for (const int& u : g1[v]) {
        dfs1(u);
    }
    tout1[v] = tt++;
}

vector<int> vset;

void dfs2(int v, int k) {
    tin2[v] = tt++;
    // cerr << "v: " << v + 1 << '\n';
    if ((int)vset.size() < k) {
        // cerr << "hui\n";
        vset.emplace_back(v);
    }
    for (const int& u : g2[v]) {
        dfs2(u, k);
    }
    tout2[v] = tt++;
}

vector<pair<int, int>> queries[maxn];
const int maxq = 1e5;
int ans[maxq];

void dfsAns1(int v) {
    par[v] = v, sz[v] = 1;
    while (!queries[v].empty()) {
        ans[queries[v].back().second] = getMinH(queries[v].back().first);
        queries[v].pop_back();
    }
    minH[v] = {tin1[v], v};
    for (const int& u : g1[v]) {
        dfsAns1(u);
        uniteSets(v, u);
    }
}

void dfsAns2(int v) {
    par[v] = v, sz[v] = 1;
    while (!queries[v].empty()) {
        ans[queries[v].back().second] = getMinH(queries[v].back().first);
        queries[v].pop_back();
    }
    minH[v] = {tin2[v], v};
    for (const int& u : g2[v]) {
        dfsAns2(u);
        uniteSets(v, u);
    }
}

vector<pair<int, int>> w1[maxn], w2[maxn];
char vis[maxn];
int dist1[maxn], dist2[maxn];

void dfsCalc1(int v) {
    // cerr << "v: " << v + 1 << ", dist1: " << dist1[v] << '\n';
    vis[v] = tt;
    for (const auto [u, delta] : w1[v]) {
        if (vis[u] < tt) {
            dist1[u] = dist1[v] + delta;
            dfsCalc1(u);
        }
    }
}

void dfsCalc2(int v) {
    // cerr << "v: " << v + 1 << ", dist2: " << dist2[v] << '\n';
    vis[v] = tt;
    for (const auto& [u, delta] : w2[v]) {
        if (vis[u] < tt) {
            dist2[u] = dist2[v] + delta;
            dfsCalc2(u);
        }
    }
}

void solve() {
    int n, k, q, t;
    cin >> n >> k >> q >> t;
    int root1 = -1, root2 = -1;
    for (int i = 0; i < n; ++i) {
        int p;
        cin >> p;
        --p;
        if (p != -2) {
            g1[p].emplace_back(i);
        } else {
            root1 = i;
        }
    }
    for (int i = 0; i < n; ++i) {
        int p;
        cin >> p;
        --p;
        if (p != -2) {
            g2[p].emplace_back(i);
        } else {
            root2 = i;
        }
    }
    tt = 0;
    dfs1(root1);
    tt = 0;
    dfs2(root2, k);
    for (const int& v : vset) {
        cout << v + 1 << ' ';
    }
    cout << endl;
    sort(vset.begin(), vset.end(), [&](const int& A, const int& B) {
        return tin1[A] < tin1[B];
    });
    for (int i = 0; i < k - 1; ++i) {
        int v = vset[i], u = vset[i + 1];
        // cerr << "v: " << v + 1 << ", u: " << u + 1 << '\n';
        queries[u].emplace_back(v, i);
    }
    dfsAns1(root1);
    int comproot1 = -1;
    vector<int> lca1(k - 1);
    for (int i = 0; i < k - 1; ++i) {
        lca1[i] = ans[i];
        // cerr << "i: " << i << ", lca1: " << lca1[i] + 1 << '\n';
        if (comproot1 == -1 || tin1[comproot1] > tin1[ans[i]]) {
            comproot1 = ans[i];
        }
        int v = vset[i], u = vset[i + 1];
        if (tin2[v] > tin2[u]) {
            swap(v, u);
        }
        queries[u].emplace_back(v, i);
    }
    dfsAns2(root2);
    int comproot2 = -1;
    vector<int> lca2(k - 1);
    for (int i = 0; i < k - 1; ++i) {
        lca2[i] = ans[i];
        // cerr << "i: " << i << ", lca2: " << lca2[i] + 1 << '\n';
        if (comproot2 == -1 || tin2[comproot2] > tin2[ans[i]]) {
            comproot2 = ans[i];
        }
    }
    for (int i = 0; i < k - 1; ++i) {
        cout << "? " << vset[i] + 1 << ' ' << vset[i + 1] + 1 << '\n';
    }
    cout << "!" << endl;
    for (int i = 0; i < k - 1; ++i) {
        int v = vset[i], u = vset[i + 1];
        int d1v, d1u, d2v, d2u;
        cin >> d1v >> d1u >> d2v >> d2u;
        w1[lca1[i]].emplace_back(v, d1v);
        w1[lca1[i]].emplace_back(u, d1u);
        w1[v].emplace_back(lca1[i], -d1v);
        w1[u].emplace_back(lca1[i], -d1u);
        w2[lca2[i]].emplace_back(v, d2v);
        w2[lca2[i]].emplace_back(u, d2u);
        w2[v].emplace_back(lca2[i], -d2v);
        w2[u].emplace_back(lca2[i], -d2u);
    }
    dist1[comproot1] = 0;
    tt = 1;
    dfsCalc1(comproot1);
    dist2[comproot2] = 0;
    ++tt;
    dfsCalc2(comproot2);
    vector<pair<int, int>> toAsk(t);
    for (int i = 0; i < t; ++i) {
        int v, u;
        cin >> v >> u;
        --v, --u;
        toAsk[i] = {v, u};
        if (tin1[v] > tin1[u]) {
            swap(v, u);
        }
        queries[u].emplace_back(v, i);
    }
    vector<int> part1(t), part2(t);
    dfsAns1(root1);
    for (int i = 0; i < t; ++i) {
        // cerr << "i: " << i << ", lca1: " << ans[i] + 1 << '\n';
        auto [v, u] = toAsk[i];
        part1[i] = -2ll * dist1[ans[i]] + dist1[v] + dist1[u];
        if (tin2[v] > tin2[u]) {
            swap(v, u);
        }
        queries[u].emplace_back(v, i);
    }
    dfsAns2(root2);
    for (int i = 0; i < t; ++i) {
        // cerr << "i: " << i << ", lca2: " << ans[i] + 1 << '\n';
        auto [v, u] = toAsk[i];
        part2[i] = -2ll * dist2[ans[i]] + dist2[v] + dist2[u];
        cout << part1[i] << ' ' << part2[i] << '\n';
    }
    cout << endl;
}

int main() {
    /*ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);*/

#ifdef LOCALa
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    int T = 1;
    cin >> T;
    while (T--) {
        solve();
        cerr << "-----------\n";
        cout << "-----------\n";
    }
#else
    int T = 1;
    // cin >> T;
    while (T--) {
        solve();
    }
#endif

    return 0;
}
# Verdict Execution time Memory Grader output
1 Correct 2239 ms 236652 KB Output is correct
2 Correct 2399 ms 240228 KB Output is correct
3 Correct 1295 ms 183484 KB Output is correct
4 Correct 1329 ms 182832 KB Output is correct
5 Correct 1413 ms 186140 KB Output is correct
6 Correct 1725 ms 196200 KB Output is correct
7 Correct 1829 ms 196296 KB Output is correct
8 Correct 1724 ms 195124 KB Output is correct
9 Correct 1374 ms 183624 KB Output is correct
10 Correct 1354 ms 185412 KB Output is correct
11 Correct 1312 ms 180908 KB Output is correct
12 Correct 1391 ms 184776 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 2415 ms 240972 KB Output is correct
2 Correct 2186 ms 235784 KB Output is correct
3 Correct 1412 ms 183692 KB Output is correct
4 Correct 1481 ms 187288 KB Output is correct
5 Correct 1384 ms 184764 KB Output is correct
6 Correct 1645 ms 193568 KB Output is correct
7 Correct 1779 ms 197564 KB Output is correct
8 Correct 1821 ms 198224 KB Output is correct
9 Correct 1601 ms 196784 KB Output is correct
10 Correct 1621 ms 197604 KB Output is correct
11 Correct 1594 ms 192504 KB Output is correct
12 Correct 1631 ms 198000 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 2040 ms 226304 KB Output is correct
2 Correct 1969 ms 226712 KB Output is correct
3 Runtime error 1010 ms 172300 KB Execution killed with signal 13
4 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Execution timed out 3550 ms 302308 KB Time limit exceeded
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Execution timed out 3577 ms 314264 KB Time limit exceeded
2 Halted 0 ms 0 KB -