Pagini recente » Cod sursa (job #1326844) | Cod sursa (job #816130) | Cod sursa (job #2587924) | Cod sursa (job #869812) | Cod sursa (job #2719481)
#include <iostream>
#include <fstream>
#include <algorithm>
#include <vector>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
const int NMAX = 100005;
const int LOGMAX = 20;
const int INF = 2e9;
vector<int>G[NMAX];
int posMin[NMAX];
int posMax[NMAX];
int lg2[3*NMAX];
int rmq[3*NMAX][LOGMAX];
int m, n, e;
void read()
{
fin >> n >> m;
for (int i = 2; i <= n; i++)
{
int x;
fin >> x;
G[x].push_back(i);
}
}
vector<int>euler;
void dfs(int u,int parent = -1)
{
for (int v : G[u])
{
if (v != parent)
{
euler.push_back(v);
dfs(v, u);
euler.push_back(u);
}
}
}
void precalc()
{
euler.push_back(-1);
for (int i = 1; i <= n; i++)
{
posMin[i] = INF;
posMax[i] = 0;
}
euler.push_back(1);
dfs(1);
e = euler.size() - 1;
for (int i = 1; i <= e ; i++)
{
posMin[euler[i]] = min(posMin[euler[i]], i);
posMax[euler[i]] = max(posMax[euler[i]], i);
}
lg2[1] = 0;
for (int i = 2; i <= e; i++)
lg2[i] = lg2[(i / 2)] + 1;
for (int i = 1; i <= e; i++) {
//fout << euler[i] << ' ';
rmq[i][0] = euler[i];
}
//fout << '\n';
for (int j = 1; (1 << j) <= e; j++)
for (int i = 1; i + (1 << j) -1 <= e; i++)
rmq[i][j] = min(rmq[i+(1<<(j-1))][j - 1], rmq[i][j-1]);
}
int RMQuery(int a, int b)
{
int l = b - a + 1;
int lg = lg2[l];
return min(rmq[a][lg], rmq[b - (1 << lg) + 1][lg]);
}
int lca(int a, int b)
{
//fout << posMin[a] << ' ' << posMax[b] << '\n';
return RMQuery(posMin[a], posMax[b]);
}
void solve()
{
while (m--)
{
int a, b;
fin >> a >> b;
fout << lca(a, b) << '\n';
}
}
int main()
{
read();
precalc();
solve();
return 0;
}