Pagini recente » Cod sursa (job #2008601) | Cod sursa (job #2933421) | Cod sursa (job #1434036) | Cod sursa (job #372497) | Cod sursa (job #1383949)
#include <fstream>
#include <vector>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
int N, M;
vector<int> V[100005];
int K;
int EULER[200005], LVL[200005], First[100005], logaritm[200005], RMQ[20][200005];
void dfs(int nod, int niv)
{
EULER[++K] = nod;
LVL[K] = niv;
First[nod] = K;
for (vector<int>::iterator it = V[nod].begin(); it != V[nod].end(); ++it)
{
dfs(*it, niv + 1);
EULER[++K] = nod;
LVL[K] = niv;
}
}
void rmq()
{
logaritm[1] = 0;
for (int i = 2; i <= K; ++i)
logaritm[i] = logaritm[i / 2] + 1;
for (int i = 1; i <= K; ++i)
RMQ[0][i] = i;
for (int i = 1; (1 << i) <= K; ++i)
{
for (int j = 1; j + (1 << (i - 1)) <= K; ++j)
{
int l = 1 << (i - 1);
if (LVL[RMQ[i - 1][j]] <= LVL[RMQ[i - 1][j + l]])
RMQ[i][j] = RMQ[i - 1][j];
else
RMQ[i][j] = RMQ[i - 1][j + l];
}
}
}
int lca(int nod1, int nod2)
{
int sol;
int start = First[nod1];
int finish = First[nod2];
if (start > finish)
swap(start, finish);
int dif = finish - start + 1;
int l = logaritm[dif];
if (LVL[RMQ[l][start]] <= LVL[RMQ[l][finish - (1 << l) + 1]])
sol = RMQ[l][start];
else
sol = RMQ[l][finish - (1 << l) + 1];
return EULER[sol];
}
int main()
{
fin >> N >> M;
for (int i = 2, nod; i <= N; ++i)
{
fin >> nod;
V[nod].push_back(i);
}
dfs(1, 0);
rmq();
for (int i = 1, nod1, nod2; i <= M; ++i)
{
fin >> nod1 >> nod2;
fout << lca(nod1, nod2) << '\n';
}
fin.close();
fout.close();
return 0;
}