Pagini recente » Cod sursa (job #149227) | Cod sursa (job #3233335) | Cod sursa (job #909227) | Cod sursa (job #260408) | Cod sursa (job #2640676)
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <queue>
#include <stack>
#include <cstring>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
const int DIM = 100005;
int n, m, x, root = 1, viz[DIM], H[DIM], Min[DIM], y, p, a, b;
vector <int> G[DIM], S;
stack <int> Stack;
struct Graph
{
int val, nod;
}rmq[20][DIM * 3 + 5];
int lg[DIM * 3 + 5];
void Read()
{
fin >> n >> m;
for (int i = 1; i < n; i++)
{
fin >> x;
G[x].push_back(i + 1);
G[i + 1].push_back(x);
}
}
void Euler()
{
Stack.push(root);
viz[root] = 1;
H[root] = 1;
int nr = 0;
p = -1;
for (int i = 1; i <= n; i++)
Min[i] = -1;
while (!Stack.empty())
{
int CrtNode = Stack.top();
S.push_back(CrtNode);
if (Min[CrtNode] < 0)
Min[CrtNode] = nr;
nr++;
p++;
bool ok = false;
vector <int> ::iterator it;
for (it = G[CrtNode].begin(); it != G[CrtNode].end(); it++)
{
if (!viz[*it])
{
viz[*it] = 1;
if (!H[*it])
H[*it] = H[CrtNode] + 1;
Stack.push(*it);
ok = true;
break;
}
}
if (!ok)
Stack.pop();
}
}
void GetPos(int NodeX, int NodeY, int& x, int& y)
{
if (Min[NodeX] < Min[NodeY])
{
x = Min[NodeX];
y = Min[NodeY];
}
else
{
x = Min[NodeY];
y = Min[NodeX];
}
}
void RMQ()
{
lg[1] = 0;
for (int i = 2; i <= p; i++)
lg[i] = lg[i / 2] + 1;
for (int i = 0; i <= p; i++)
{
rmq[0][i].val = H[S[i]];
rmq[0][i].nod = S[i];
}
for (int i = 1; (1 << i) <= p; i++)
{
for (int j = 0; j <= p - (1 << i) + 1; j++)
{
int l = (1 << (i - 1));
if (rmq[i - 1][j].val < rmq[i - 1][j + l].val)
{
rmq[i][j].val = rmq[i - 1][j].val;
rmq[i][j].nod = rmq[i - 1][j].nod;
}
else
{
rmq[i][j].val = rmq[i - 1][j + l].val;
rmq[i][j].nod = rmq[i - 1][j + l].nod;
}
}
}
}
int QueryRMQ(int x, int y)
{
int diff = y - x + 1;
int l = lg[diff];
int sh = diff - (1 << l);
if (rmq[l][x].val < rmq[l][x + sh].val)
return rmq[l][x].nod;
return rmq[l][x + sh].nod;
}
void Query()
{
while (m--)
{
fin >> a >> b;
GetPos(a, b, x, y);
fout << QueryRMQ(x, y) << '\n';
}
}
int main()
{
Read();
Euler();
RMQ();
Query();
}