#pragma GCC optimize("O3", "Ofast")
// #pragma GCC optimize("avx", "avx2")
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6;
vector<int> g1[maxn], g2[maxn];
int h1[maxn], h2[maxn], tin1[maxn], tin2[maxn], tt;
int par1[maxn], par2[maxn], jump1[maxn], jump2[maxn];
vector<int> vset;
void dfs1(int v, int k) {
if (tin2[v] < k) {
vset.emplace_back(v);
}
tin1[v] = tt++;
for (const int& u : g1[v]) {
h1[u] = h1[v] + 1;
if (h1[jump1[jump1[v]]] - h1[jump1[v]] == h1[jump1[v]] - h1[v]) {
jump1[u] = jump1[jump1[v]];
} else {
jump1[u] = v;
}
dfs1(u, k);
}
}
void dfs2(int v) {
tin2[v] = tt++;
for (const int& u : g2[v]) {
h2[u] = h2[v] + 1;
if (h2[jump2[jump2[v]]] - h2[jump2[v]] == h2[jump2[v]] - h2[v]) {
jump2[u] = jump2[jump2[v]];
} else {
jump2[u] = v;
}
dfs2(u);
}
}
int getLca1(int v, int u) {
if (h1[v] < h1[u]) { swap(v, u); }
while (h1[v] != h1[u]) {
if (h1[jump1[v]] > h1[u]) {
v = jump1[v];
} else {
v = par1[v];
}
}
while (v != u) {
if (jump1[v] != jump1[u]) {
v = jump1[v], u = jump1[u];
} else {
v = par1[v], u = par1[u];
}
}
return v;
}
int getLca2(int v, int u) {
if (h2[v] < h2[u]) { swap(v, u); }
while (h2[v] != h2[u]) {
if (h2[jump2[v]] > h2[u]) {
v = jump2[v];
} else {
v = par2[v];
}
}
while (v != u) {
if (jump2[v] != jump2[u]) {
v = jump2[v], u = jump2[u];
} else {
v = par2[v], u = par2[u];
}
}
return v;
}
const int maxq = 1e5;
int newV1[maxn];
vector<pair<int, int>> w1[2 * maxq], w2[maxq];
char vis[2 * maxq];
int dist1[2 * maxq], dist2[maxq];
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) {
// newV1[i] = -1;
cin >> par1[i];
--par1[i];
if (par1[i] != -2) {
g1[par1[i]].emplace_back(i);
} else {
par1[i] = i;
jump1[i] = i;
root1 = i;
}
}
for (int i = 0; i < n; ++i) {
cin >> par2[i];
--par2[i];
if (par2[i] != -2) {
g2[par2[i]].emplace_back(i);
} else {
par2[i] = i;
jump2[i] = i;
root2 = i;
}
}
tt = 0;
dfs2(root2);
tt = 0;
dfs1(root1, k);
vector<int> comp1(2 * k - 1);
for (int i = 0; i < k; ++i) {
cout << vset[i] + 1 << ' ';
comp1[i] = vset[i];
}
cout << endl;
/*for (int i = 0; i < n; ++i) {
dsu.minH[i] = {tin1[i], i};
}*/
vector<int> lca1(k - 1), lca2(k - 1);
int comproot1 = -1, comproot2 = -1;
for (int i = 0; i < k - 1; ++i) {
int v = vset[i], u = vset[i + 1];
// cerr << "v: " << v + 1 << ", u: " << u + 1 << '\n';
lca1[i] = getLca1(v, u);
lca2[i] = getLca2(v, u);
comp1[k + i] = lca1[i];
if (comproot1 == -1 || tin1[comproot1] > tin1[lca1[i]]) {
comproot1 = lca1[i];
}
if (comproot2 == -1 || tin2[comproot2] > tin2[lca2[i]]) {
comproot2 = lca2[i];
}
}
sort(comp1.begin(), comp1.end(), [&](const int& A, const int& B) {
return tin1[A] < tin1[B];
});
comp1.resize(unique(comp1.begin(), comp1.end()) - comp1.begin());
for (int i = 0; i < (int)comp1.size(); ++i) {
newV1[comp1[i]] = 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;
int newlca1 = newV1[lca1[i]], newlca2 = tin2[lca2[i]];
w1[newlca1].emplace_back(newV1[v], d1v);
w1[newlca1].emplace_back(newV1[u], d1u);
w1[newV1[v]].emplace_back(newlca1, -d1v);
w1[newV1[u]].emplace_back(newlca1, -d1u);
w2[newlca2].emplace_back(tin2[v], d2v);
w2[newlca2].emplace_back(tin2[u], d2u);
w2[tin2[v]].emplace_back(newlca2, -d2v);
w2[tin2[u]].emplace_back(newlca2, -d2u);
}
dist1[newV1[comproot1]] = 0;
tt = 1;
dfsCalc1(newV1[comproot1]);
dist2[tin2[comproot2]] = 0;
++tt;
dfsCalc2(tin2[comproot2]);
vector<int> part1(t), part2(t);
for (int i = 0; i < t; ++i) {
int v, u;
cin >> v >> u;
--v, --u;
part1[i] = -2ll * dist1[newV1[getLca1(v, u)]] + dist1[newV1[v]] + dist1[newV1[u]];
part2[i] = -2ll * dist2[tin2[getLca2(v, u)]] + dist2[tin2[v]] + dist2[tin2[u]];
}
for (int i = 0; i < t; ++i) {
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;
}
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
838 ms |
159764 KB |
Output is correct |
2 |
Correct |
1047 ms |
164288 KB |
Output is correct |
3 |
Correct |
595 ms |
115584 KB |
Output is correct |
4 |
Correct |
526 ms |
115532 KB |
Output is correct |
5 |
Correct |
686 ms |
118168 KB |
Output is correct |
6 |
Correct |
773 ms |
127004 KB |
Output is correct |
7 |
Correct |
925 ms |
126768 KB |
Output is correct |
8 |
Correct |
814 ms |
124160 KB |
Output is correct |
9 |
Correct |
559 ms |
115716 KB |
Output is correct |
10 |
Correct |
658 ms |
118036 KB |
Output is correct |
11 |
Correct |
566 ms |
112220 KB |
Output is correct |
12 |
Correct |
620 ms |
115780 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1072 ms |
164716 KB |
Output is correct |
2 |
Correct |
879 ms |
159660 KB |
Output is correct |
3 |
Correct |
678 ms |
114888 KB |
Output is correct |
4 |
Correct |
750 ms |
117856 KB |
Output is correct |
5 |
Correct |
704 ms |
116748 KB |
Output is correct |
6 |
Correct |
812 ms |
124280 KB |
Output is correct |
7 |
Correct |
900 ms |
127236 KB |
Output is correct |
8 |
Correct |
952 ms |
127728 KB |
Output is correct |
9 |
Correct |
790 ms |
126008 KB |
Output is correct |
10 |
Correct |
848 ms |
126940 KB |
Output is correct |
11 |
Correct |
729 ms |
122380 KB |
Output is correct |
12 |
Correct |
826 ms |
126836 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
622 ms |
153604 KB |
Output is correct |
2 |
Correct |
685 ms |
153228 KB |
Output is correct |
3 |
Correct |
412 ms |
106748 KB |
Output is correct |
4 |
Correct |
478 ms |
106916 KB |
Output is correct |
5 |
Correct |
400 ms |
106900 KB |
Output is correct |
6 |
Correct |
528 ms |
116044 KB |
Output is correct |
7 |
Correct |
549 ms |
116700 KB |
Output is correct |
8 |
Correct |
599 ms |
115508 KB |
Output is correct |
9 |
Correct |
486 ms |
113964 KB |
Output is correct |
10 |
Correct |
534 ms |
115232 KB |
Output is correct |
11 |
Correct |
508 ms |
113864 KB |
Output is correct |
12 |
Correct |
483 ms |
113504 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1544 ms |
217588 KB |
Output is correct |
2 |
Correct |
1607 ms |
218564 KB |
Output is correct |
3 |
Correct |
1184 ms |
124932 KB |
Output is correct |
4 |
Correct |
1137 ms |
125532 KB |
Output is correct |
5 |
Correct |
1150 ms |
125060 KB |
Output is correct |
6 |
Correct |
1428 ms |
144900 KB |
Output is correct |
7 |
Correct |
1503 ms |
145292 KB |
Output is correct |
8 |
Correct |
1488 ms |
144800 KB |
Output is correct |
9 |
Correct |
1337 ms |
140896 KB |
Output is correct |
10 |
Correct |
1328 ms |
140420 KB |
Output is correct |
11 |
Correct |
1251 ms |
140680 KB |
Output is correct |
12 |
Correct |
1268 ms |
141016 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
2156 ms |
228620 KB |
Output is correct |
2 |
Correct |
2052 ms |
228284 KB |
Output is correct |
3 |
Correct |
1288 ms |
133200 KB |
Output is correct |
4 |
Correct |
1413 ms |
137728 KB |
Output is correct |
5 |
Correct |
1294 ms |
132032 KB |
Output is correct |
6 |
Correct |
1958 ms |
157412 KB |
Output is correct |
7 |
Correct |
1756 ms |
152332 KB |
Output is correct |
8 |
Correct |
1874 ms |
154772 KB |
Output is correct |
9 |
Correct |
1587 ms |
150548 KB |
Output is correct |
10 |
Correct |
1611 ms |
148820 KB |
Output is correct |
11 |
Correct |
1610 ms |
149376 KB |
Output is correct |
12 |
Correct |
1625 ms |
151720 KB |
Output is correct |