Pagini recente » Cod sursa (job #1666024) | Cod sursa (job #2050275) | Cod sursa (job #1139320) | Cod sursa (job #2937577) | Cod sursa (job #2308198)
#include <iostream>
#include <fstream>
#include <algorithm>
#include <vector>
#include <cmath>
#include <climits>
using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
const int NMAX = 100000;
vector<int> g[NMAX + 5], p[NMAX + 5], gp[NMAX + 5];
int dim[NMAX + 5], dad[NMAX + 5], lvl[NMAX + 5];
int path[NMAX + 5], npaths, path_dad[NMAX + 5], h[NMAX + 5];
void dfs(int node) {
dim[node] = 1;
int from, mx = -1;
for(auto it : g[node])
if(it != dad[node]) {
lvl[it] = lvl[node] + 1;
dfs(it);
dim[node] += dim[it];
if(dim[it] > mx) {
mx = dim[it];
from = it;
}
}
if(dim[node] == 1) {
npaths ++;
p[npaths].push_back(node);
path_dad[npaths] = node;
path[node] = npaths;
} else {
p[path[from]].push_back(node);
path_dad[path[from]] = node;
path[node] = path[from];
}
}
void computeh(int node, int d) {
for(auto it : gp[node])
if(it != d) {
h[it] = h[node] + 1;
computeh(it, node);
}
}
int main() {
int n, m;
in >> n >> m;
for(int i = 2; i <= n; i ++) {
int x;
in >> x;
dad[i] = x;
g[x].push_back(i);
g[i].push_back(x);
}
dim[1] = 1;
lvl[1] = 1;
dfs(1);
int start = 1;
for(int i = 1; i <= npaths; i ++) {
if(dad[path_dad[i]] != 0) {
gp[i].push_back(path[dad[path_dad[i]]]);
gp[path[dad[path_dad[i]]]].push_back(i);
} else
start = i;
}
h[start] = 1;
computeh(start, 0);
vector<int> lg(n + 1, 0);
for(int i = 2; i <= n; i ++)
lg[i] = lg[i >> 1] + 1;
vector<vector<int>> dp(lg[npaths] + 1, vector<int> (npaths + 1, 0));
vector<vector<int>> dp2(lg[npaths] + 1, vector<int> (npaths + 1, 0));
for(int i = 1; i <= npaths; i ++) {
dp[0][i] = path[dad[path_dad[i]]];
dp2[0][i] = dad[path_dad[i]];
}
for(int i = 1; i <= lg[npaths]; i ++)
for(int j = 1; j <= npaths; j ++) {
dp[i][j] = dp[i - 1][dp[i - 1][j]];
dp2[i][j] = dp2[i - 1][dp[i - 1][j]];
}
for(int i = 1; i <= m; i ++) {
int x, y;
in >> x >> y;
if(h[path[x]] < h[path[y]])
swap(x, y);
int pathx = path[x], pathy = path[y];
int aux;
if(lvl[x] > lvl[y])
aux = y;
else
aux = x;
for(int step = lg[npaths]; step >= 0; step --)
if(dp[step][pathx] != 0 && h[pathy] <= h[dp[step][pathx]]) {
aux = dp2[step][pathx];
pathx = dp[step][pathx];
}
int ans;
if(pathx != pathy) {
for(int step = lg[npaths]; step >= 0; step --)
if(dp[step][pathx] != 0 && dp[step][pathy] != 0 && dp[step][pathx] != dp[step][pathy]) {
pathx = dp[step][pathx];
pathy = dp[step][pathy];
}
int auxx = dp2[0][pathx];
int auxy = dp2[0][pathy];
if(lvl[auxx] > lvl[auxy])
ans = auxy;
else
ans = auxx;
} else {
if(lvl[aux] < lvl[y])
ans = aux;
else
ans = y;
}
out << ans << "\n";
}
return 0;
}