Submission #916053

#TimeUsernameProblemLanguageResultExecution timeMemory
916053AlcabelPrize (CEOI22_prize)C++17
35 / 100
3577 ms314264 KiB
#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 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...