Pagini recente » Cod sursa (job #3163568) | wellcodesimulareclasa11-12-10martie | Cod sursa (job #1515850) | Cod sursa (job #2867607) | Cod sursa (job #2308204)
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cmath>
#include <climits>
using namespace std;
const int NMAX = 100000;
vector<int> g[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 ++;
path_dad[npaths] = node;
path[node] = npaths;
} else {
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 readInt () {
bool minus = false;
int result = 0;
char ch;
ch = getchar();
while (true) {
if (ch == '-') break;
if (ch >= '0' && ch <= '9') break;
ch = getchar();
}
if (ch == '-') minus = true; else result = ch-'0';
while (true) {
ch = getchar();
if (ch < '0' || ch > '9') break;
result = result*10 + (ch - '0');
}
if (minus)
return -result;
else
return result;
}
int main() {
freopen("lca.in", "r", stdin);
freopen("lca.out", "w", stdout);
int n, m;
n = readInt();
m = readInt();
for(int i = 2; i <= n; i ++) {
int x;
x = readInt();
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;
x = readInt();
y = readInt();
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;
}
printf("%d\n", ans);
}
return 0;
}