| Task: | Company Queries II |
| Sender: | Ciphra |
| Submission time: | 2025-10-23 17:46:35 +0300 |
| Language: | C++ (C++17) |
| Status: | READY |
| Result: | ACCEPTED |
| test | verdict | time | |
|---|---|---|---|
| #1 | ACCEPTED | 0.00 s | details |
| #2 | ACCEPTED | 0.01 s | details |
| #3 | ACCEPTED | 0.00 s | details |
| #4 | ACCEPTED | 0.00 s | details |
| #5 | ACCEPTED | 0.00 s | details |
| #6 | ACCEPTED | 0.52 s | details |
| #7 | ACCEPTED | 0.30 s | details |
| #8 | ACCEPTED | 0.42 s | details |
| #9 | ACCEPTED | 0.56 s | details |
| #10 | ACCEPTED | 0.49 s | details |
| #11 | ACCEPTED | 0.00 s | details |
| #12 | ACCEPTED | 0.60 s | details |
Code
#include <iostream>
#include <queue>
#include <utility>
#include <vector>
const int MAX_DEPTH = 18; // ceil(log(n=2*10^5)) ~ 18
int lca(int a, int b, std::vector<std::vector<int>>& up, std::vector<int>& depth){
if (depth[a] < depth[b]) std::swap(a, b);
int diff = depth[a] - depth[b];
for (int j = 0; j < MAX_DEPTH; ++j)
if (diff & (1 << j)) a = up[a][j]; //move "a" up by exactly "diff" levels.
if (a == b) return a;
// Get largest possible ancestor, if the ancestors isn't equal, we haven't converged yet, and it is safe to lift both a and b to that ancestor.
// When they reach that, the effective depth left to reach the root is reduced exactly by j levels, so we don't need to check the previous levels again.
// In the case, the furthest ancestors are equal, we continue the loop in case of a lower common ancestor.
for (int j = MAX_DEPTH-1; j >= 0; --j)
if (up[a][j] != up[b][j]) {
a = up[a][j];
b = up[b][j];
}
return up[a][0];
}
int main() {
int n, q;
std::cin >> n >> q;
std::vector<std::vector<int>> up(n+1, std::vector<int>(MAX_DEPTH));
std::vector<int> depth(n+1);
// for bfs to get depth
std::vector<std::vector<int>> adj(n+1);
for (int i = 2; i <= n; ++i) {
int boss;
std::cin >> boss;
adj[boss].push_back(i);
adj[i].push_back(boss);
up[i][0] = boss;
}
// initialize root
up[1][0] = 1;
depth[1] = 0;
std::queue<int> queue;
queue.push(1);
while (!queue.empty()) {
int v = queue.front(); queue.pop();
for (int u : adj[v]) {
if (u != up[v][0]) {
depth[u] = depth[v] + 1;
queue.push(u);
}
}
}
// binary lifting table
for (int j = 1; j < MAX_DEPTH; ++j)
for (int v = 1; v <= n; ++v)
up[v][j] = up[ up[v][j-1] ][j-1];
std::vector<std::pair<int, int>> queries(q);
for(int i = 0; i<q; ++i){
std::cin >> queries[i].first >> queries[i].second;
}
for(int i = 0; i<q; ++i){
std::cout << lca(queries[i].first, queries[i].second, up, depth) << '\n';
}
}
Test details
Test 1
Verdict: ACCEPTED
| input |
|---|
| 10 10 1 2 3 4 5 6 7 8 9 6 9 8 10 10 3 ... |
| correct output |
|---|
| 6 8 3 1 8 ... |
| user output |
|---|
| 6 8 3 1 8 ... |
Test 2
Verdict: ACCEPTED
| input |
|---|
| 10 10 1 1 1 1 1 1 1 1 1 1 7 3 4 4 1 ... |
| correct output |
|---|
| 1 1 1 1 1 ... |
| user output |
|---|
| 1 1 1 1 1 ... |
Test 3
Verdict: ACCEPTED
| input |
|---|
| 10 10 1 1 1 1 2 3 4 4 1 1 8 2 7 8 3 ... |
| correct output |
|---|
| 1 1 1 1 1 ... |
| user output |
|---|
| 1 1 1 1 1 ... |
Test 4
Verdict: ACCEPTED
| input |
|---|
| 10 10 1 1 3 1 2 2 5 3 9 7 2 7 6 3 9 ... |
| correct output |
|---|
| 2 2 3 1 1 ... |
| user output |
|---|
| 2 2 3 1 1 ... |
Test 5
Verdict: ACCEPTED
| input |
|---|
| 10 10 1 2 3 2 5 3 2 2 4 6 1 1 3 1 9 ... |
| correct output |
|---|
| 1 1 1 2 2 ... |
| user output |
|---|
| 1 1 1 2 2 ... |
Test 6
Verdict: ACCEPTED
| input |
|---|
| 200000 200000 1 2 3 4 5 6 7 8 9 10 11 12 13 ... |
| correct output |
|---|
| 74862 8750 16237 72298 58111 ... |
| user output |
|---|
| 74862 8750 16237 72298 58111 ... |
Test 7
Verdict: ACCEPTED
| input |
|---|
| 200000 200000 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ... |
| correct output |
|---|
| 1 1 1 1 1 ... |
| user output |
|---|
| 1 1 1 1 1 ... |
Test 8
Verdict: ACCEPTED
| input |
|---|
| 200000 200000 1 2 1 2 3 2 1 6 3 1 10 12 13 4... |
| correct output |
|---|
| 1 2 2 2 1 ... |
| user output |
|---|
| 1 2 2 2 1 ... |
Test 9
Verdict: ACCEPTED
| input |
|---|
| 200000 200000 1 2 3 4 5 6 7 8 9 10 11 12 13 ... |
| correct output |
|---|
| 2796 633 633 151 2690 ... |
| user output |
|---|
| 2796 633 633 151 2690 ... |
Test 10
Verdict: ACCEPTED
| input |
|---|
| 200000 200000 1 2 3 4 5 6 7 8 9 10 11 12 13 ... |
| correct output |
|---|
| 365 73 103 365 216 ... |
| user output |
|---|
| 365 73 103 365 216 ... |
Test 11
Verdict: ACCEPTED
| input |
|---|
| 2 4 1 1 1 1 2 2 1 ... |
| correct output |
|---|
| 1 1 1 2 |
| user output |
|---|
| 1 1 1 2 |
Test 12
Verdict: ACCEPTED
| input |
|---|
| 200000 200000 1 1 2 3 4 5 6 7 8 9 10 11 12 1... |
| correct output |
|---|
| 27468 6353 27468 6353 6353 ... |
| user output |
|---|
| 27468 6353 27468 6353 6353 ... |
