Pagini recente » Cod sursa (job #189674) | Cod sursa (job #1323270) | Cod sursa (job #1092097) | Cod sursa (job #589356) | Cod sursa (job #561478)
Cod sursa(job #561478)
#include <fstream>
#include <vector>
#include <cmath>
using namespace std;
const int maxn = 100010;
int t[maxn], p[maxn], level[maxn];
vector <int> sons[maxn];
int findLevel(int nod) {
int max = 1;
for (int i = 0; i < sons[nod].size(); i++) {
level[sons[nod][i]] = level[nod] + 1;
int x = findLevel(sons[nod][i]);
if (x > max)
max = x;
}
if (sons[nod].size() == 0)
return level[nod];
return max;
}
void findSegment(int nod, int r) {
if (level[nod] <= r)
p[nod] = 1;
else
if (level[nod] % r == 1)
p[nod] = t[nod];
else
p[nod] = p[t[nod]];
for (int i = 0; i < sons[nod].size(); i++)
findSegment(sons[nod][i], r);
}
int findAncestor(int a, int b) {
while (p[a] != p[b]) {
if (level[p[a]] > level[p[b]])
a = p[a];
else
b = p[b];
}
while (a != b) {
a = t[a];
b = t[b];
}
return a;
}
int main() {
ifstream f("lca.in");
ofstream g("lca.out");
int n, m;
f >> n >> m;
int x;
t[1] = 0;
level[1] = 1;
for (int i = 2; i <= n; i++) {
f >> x;
t[i] = x;
sons[x].push_back(i);
}
int max_level = findLevel(1);
int r = sqrt(max_level);
findSegment(1, r);
int a, b;
for (int li = 1; li <= m; li++) {
f >> a >> b;
int x = findAncestor(a, b);
g << x << '\n';
}
return 0;
}