Pagini recente » Cod sursa (job #444780) | Cod sursa (job #1437340) | Cod sursa (job #2770144) | Cod sursa (job #2196114) | Cod sursa (job #1938495)
#include <fstream>
#include <vector>
#include <iostream>
#define NMAX 100002
#define LMAX 20
#define doi_la(i) (1 << i)
using namespace std;
vector <int> v[NMAX];
int rmq[LMAX][NMAX << 2], n, m, lg[NMAX << 1], nivel[NMAX << 1], euler[NMAX << 1], first[NMAX];
int k;
ifstream f("lca.in");
ofstream g("lca.out");
void citire () {
f >> n >> m;
int x, i;
for (i = 2; i <= n; ++i) {
f >> x;
v[x].push_back(i);
}
}
void dfs (int x, int niv) {
euler[++k] = x;
nivel[k] = niv;
first[x] = k;
vector <int> :: iterator it;
for (it = v[x].begin(); it != v[x].end(); ++it) {
dfs(*it, niv+1);
euler[++k] = x;
nivel[k] = niv;
}
}
void rm() {
int i, j, l;
for (i = 2; i <= k; ++i)
lg[i] = lg[i >> 1] + 1;
for (i = 1; i <= k; ++i)
rmq[0][i] = i;
for (i = 1; doi_la(i) < k; ++i)
for (j = 1; j <= k - doi_la(i); ++j) {
l = doi_la((i - 1));
rmq[i][j] = rmq[i - 1][j];
if (nivel[rmq[i - 1][j+l]] < nivel[rmq[i][j]]) rmq[i][j] = rmq[i - 1][j + l];
}
}
int lca(int x, int y) {
int diff, l, sol, sh;
int a = first[x], b = first[y];
if (a > b) swap(a, b);
diff = b - a + 1;
l = lg[diff];
sol = rmq[l][a];
sh = diff - doi_la(l);
if (nivel[sol] > nivel[rmq[l][a + sh]])
sol = rmq[l][a + sh];
return euler[sol];
}
int main()
{
citire();
dfs(1, 0);
rm();
int x, y;
for (int i = 1; i <= m; ++i) {
f >> x >> y;
g << lca(x, y) << "\n";
}
return 0;
}