Pagini recente » Cod sursa (job #385153) | Cod sursa (job #1234634) | Cod sursa (job #2564052) | Cod sursa (job #1029453) | Cod sursa (job #1512805)
#include <bits/stdc++.h>
using namespace std;
int t[100005], n, start;
bool viz[100005];
vector<int> L[100005];
vector< pair<int, int> > euler; //200 005
int first[100005];
FILE *g = fopen("lca.out", "w");
void dfs(int where, int level) {
first[where] = euler.size() - 1;
for(int i = 0; i < L[where].size(); i ++) {
euler.push_back(make_pair(L[where][i], level + 1));
dfs(L[where][i], level + 1);
euler.push_back(make_pair(where, level));
}
}
int M[200005][20];
int lca(int a, int b) {
if(a > b) {
int aux = a;
a = b;
b = aux;
}
int k = log2(b - a + 1);
int ret;
if(euler[M[a][k]].second < euler[M[b - (1 << k) + 1][k]].second)
ret = M[a][k];
else ret = M[b - (1 << k) + 1][k];
return euler[ret].first;
}
int main()
{
FILE *f = fopen("lca.in", "r");
int m, x, y;
fscanf(f, "%d %d", &n, &m);
for(int i = 2; i <= n; i ++) {
fscanf(f, "%d", &t[i]);
viz[i] = true;
L[t[i]].push_back(i);
}
for(int i = 1; i <= n; i ++) {
if(!viz[i])
start = i;
}
euler.push_back(make_pair(start, 0));
dfs(start, 0);
n = euler.size();
for(int i = 0; i < n; i ++)
M[i][0] = i;
for(int j = 1; 1 << j < n; j ++) {
for(int i = 0; i + (1 << j) - 1 < n; i ++) {
if(euler[M[i][j - 1]].second >= euler[M[i + (1 << (j - 1))][j - 1]].second)
M[i][j] = M[i + (1 << (j - 1))][j - 1];
else M[i][j] = M[i][j - 1];
}
}
for(int i = 1; i <= m; i ++) {
fscanf(f, "%d %d", &x, &y);
fprintf(g, "%d\n", lca(first[x], first[y]));
}
return 0;
}