Pagini recente » Cod sursa (job #820487) | Cod sursa (job #483057) | Cod sursa (job #2275074) | Cod sursa (job #960532) | Cod sursa (job #2836788)
#include <iostream>
#include <vector>
#include <fstream>
using namespace std;
ifstream fin ("lca.in");
ofstream fout ("lca.out");
const int maxN = 1e5 + 5;
const int INF = 1e9;
const int maxLog = 25;
struct Euler {
int n, i;
}euler[4 * maxN];
vector <int> g[maxN];
int poz[maxN], logg[4*maxN], rmq[maxLog][4*maxN], eulerSize = 0;
bool vizitat[maxN];
void dfs(int node, int depth) {
vizitat[node] = true;
euler[++eulerSize].i = node;
euler[eulerSize].n = depth;
poz[node] = eulerSize;
for(int to : g[node])
if(vizitat[to] == false) {
dfs(to, depth + 1);
euler[++eulerSize].i = node;
euler[eulerSize].n = depth;
}
}
int main() {
int n, q; fin >> n >> q;
for(int i = 2; i <= n; ++i) {
int x; fin >> x;
g[x].push_back(i);
g[i].push_back(x);
}
dfs(1, 0);
logg[0] = logg[1] = 0;
for(int i = 2; i <= eulerSize; ++i)
logg[i] = logg[i/2] + 1;
for(int i = 1; i <= eulerSize; ++i)
rmq[0][i] = i;
for(int step = 1; (1 << step) <= eulerSize; ++step)
for(int i = 1; i + (1 << step) - 1 <= eulerSize; ++i)
if(euler[rmq[step-1][i]].n <= euler[rmq[step-1][i+(1<<(step-1))]].n)
rmq[step][i] = rmq[step-1][i];
else
rmq[step][i] = rmq[step-1][i+(1<<(step-1))];
for(int i = 1; i <= q; ++i) {
int u, v; fin >> u >> v;
int l = min(poz[u], poz[v]);
int r = max(poz[u], poz[v]);
int lg = logg[r-l+1];
if(euler[rmq[lg][l]].n < euler[rmq[lg][r-(1<<lg)] + 1].n)
fout << euler[rmq[lg][l]].i << "\n";
else
fout << euler[rmq[lg][r-(1<<lg)] + 1].i << "\n";
}
return 0;
}