Pagini recente » Profil dornescuvlad | Cod sursa (job #1602012) | Cod sursa (job #488995) | Cod sursa (job #1958498) | Cod sursa (job #1833739)
#include <bits/stdc++.h>
#define NMAX 100005
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");
int N, M, level[NMAX], dad[NMAX], intervalDad[NMAX], H;
vector < int > graph[NMAX];
void readInput() {
f >> N >> M;
H = sqrt(N);
for (int i = 2; i <= N; ++i) {
f >> dad[i];
graph[dad[i]].push_back(i);
}
}
void dfs(int node, int intervalFather, int currentLevel) {
level[node] = currentLevel;
intervalDad[node] = intervalFather;
if (currentLevel % H == 0) {
intervalFather = node;
}
for (auto it : graph[node]) {
dfs(it, intervalFather, currentLevel + 1);
}
}
int lca(int node1, int node2) {
/* Aduc nodurile in acelasi interval */
while (intervalDad[node1] != intervalDad[node2]) {
if (level[node1] > level[node2]) {
node1 = intervalDad[node1];
} else {
node2 = intervalDad[node2];
}
}
/* "Urc" in arbore cu fiecare nod pana cand acestea sunt egale */
while (node1 != node2) {
/* La fiecare pas, urc cu nodul care are nivelul mai mare*/
if (level[node1] > level[node2]) {
node1 = dad[node1];
} else {
node2 = dad[node2];
}
}
return node1;
}
void computeQueries() {
for (int i = 1; i <= M; ++i) {
int node1, node2;
f >> node1 >> node2;
g << lca(node1, node2) << '\n';
}
}
int main() {
readInput();
dfs(1, 0, 0);
computeQueries();
return 0;
}