Pagini recente » Cod sursa (job #1187753) | Cod sursa (job #1201189) | Cod sursa (job #774244) | Cod sursa (job #220832) | Cod sursa (job #2119798)
#include <bits/stdc++.h>
#define in "lca.in"
#define out "lca.out"
using namespace std;
ifstream fin(in);
ofstream fout(out);
int n;
int rmq[22][400005]; /// nodul minim din secventa (i, 2^j + i)
int E[400005],k; /// reprezentarea Euler a arborelui
int niv[400005]; /// nivelul minim
int poz[100003];
int P[100003]; /// vectorul cu exponentii puterilor lui 2
vector <int> L[100003]; /// listele de adiacenta
void Euler(int nod, int nivel)
{
E[++k] = nod;
niv[k] = nivel;
poz[nod] = k;
for(auto i : L[nod])
{
Euler(i,nivel+1);
E[++k] = nod;
niv[k] = nivel;
}
}
void Puteri()
{
int i;
P[1] = 0;
for (i = 2; i <= k; i++)
P[i] = 1 + P[i/2];
}
void RMQ()
{
int i,N,j,x,y;
for(i = 1; i <= k; i++)
rmq[0][i] = i;
N = P[k];
for(i = 1; i <= N; i++)
for(j = 1; j <= k - (1 << i) + 1; j++)
{
x = niv[rmq[i-1][j]];
y = niv[rmq[i-1][j + (1<<(i-1)) ]];
if(x < y) rmq[i][j] = rmq[i-1][j];
else rmq[i][j] = rmq[i-1][j + (1<<(i-1))];
}
}
int main()
{
int Q,i,j,x,y;
fin >> n >> Q;
/// nodul 1 este radacina
for (i = 2; i <= n; i++)
{
fin >> x;
L[x].push_back(i);
}
Euler(1,1);
Puteri();
RMQ();
while (Q--)
{
fin >> x >> y;
x = poz[x];
y = poz[y];
if (x > y) swap(x,y);
int len = P[y-x+1];
i = rmq[len][x];
j = rmq[len][y - (1<<len) + 1];
if (niv[i] < niv[j]) fout << E[i] << "\n";
else fout << E[j] << "\n";
}
fin.close();
fout.close();
return 0;
}