Pagini recente » Cod sursa (job #892468) | Cod sursa (job #939780) | Cod sursa (job #220857) | Cod sursa (job #303950) | Cod sursa (job #2332586)
#include <fstream>
#include <vector>
using namespace std;
#define FILENAME "lca"
ifstream fin (FILENAME".in");
ofstream fout(FILENAME".out");
const int MAXN = 100000 + 16;
const int MAXLOGN = 20;
int RMQ[MAXLOGN][MAXN << 2];
int E[MAXN << 1], L[MAXN << 1], H[MAXN], Log[MAXN];
int N, M, K;
vector < int > Fii[MAXN];
void E_precalc(int, int);
void RMQ_precalc();
int RMQ_query(int, int);
int main()
{
fin >> N >> M;
for(int i = 2; i <= N; ++i)
{
int x;
fin >> x;
Fii[x].push_back(i);
}
E_precalc(1, 0);
RMQ_precalc();
while(M--)
{
int x, y;
fin >> x >> y;
fout << RMQ_query(x, y) << '\n';
}
return 0;
}
int RMQ_query(int x, int y)
{
int Result = 0, diff, len, sh;
x = H[x], y = H[y];
if(x > y)
swap(x, y);
diff = y - x + 1;
len = Log[diff];
Result = RMQ[len][x];
sh = diff - (1 << len);
if(L[Result] > L[ RMQ[len][x + sh] ] )
Result = RMQ[len][x + sh];
return E[Result];
}
void RMQ_precalc()
{
for(int i = 2; i <= K; ++i)
Log[i] = Log[i>>1] + 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 len = 1 << (i - 1);
RMQ[i][j] = RMQ[i-1][j];
if(L[ RMQ[i-1][j + len] ] < L[ RMQ[i][j] ])
RMQ[i][j] = RMQ[i-1][j + len];
}
}
void E_precalc(int node, int level)
{
++K;
E[K] = node;
L[K] = level;
H[node] = K;
vector < int > :: iterator it;
for(it = Fii[node].begin(); it != Fii[node].end(); ++it)
{
E_precalc(*it, level + 1);
++K;
E[K] = node;
L[K] = level;
}
}