Pagini recente » Cod sursa (job #1292058) | Cod sursa (job #1700549) | Cod sursa (job #2671946) | Cod sursa (job #1793916) | Cod sursa (job #1961056)
#include <cstdio>
#include <cmath>
#include <vector>
using namespace std;
const int N = 100005;
int n, m;
int tati[N];
vector<int> vecini[N];
vector<pair<int, int> > euler;
int rmq[4 * N][20];
int firstAparition[N];
int nr = 0;
void citire()
{
scanf("%d %d", &n, &m);
for(int i = 1; i < n; i++)
{
scanf("%d", &tati[i]);
tati[i]--;
vecini[tati[i]].push_back(i);
}
for(int i = 0; i < n; i++)
{
firstAparition[i] = -1;
}
}
void dfs(int x, int adancime)
{
int l = vecini[x].size();
if(firstAparition[x] == -1)
{
firstAparition[x] = nr;
}
for(int i = 0; i < l; i++)
{
euler.push_back(make_pair(adancime, x));
nr++;
dfs(vecini[x][i], adancime + 1);
}
euler.push_back(make_pair(adancime, x));
nr++;
}
void construireEuler()
{
dfs(0, 0);
}
void construireRmq()
{
int l = euler.size();
int lg = log2(l);
for(int i = 0; i < l; i++)
{
rmq[i][0] = i;
}
for(int i = 1; i <= lg; i++)
{
for(int j = 0; j < l; j++)
{
if(j + (1 << (i - 1)) < l)
{
if(euler[rmq[j][i - 1]].first < euler[rmq[j + (1 << (i - 1))][i - 1]].first)
{
rmq[j][i] = rmq[j][i - 1];
}
else
{
rmq[j][i] = rmq[j + (1 << (i - 1))][i - 1];
}
}
else
{
rmq[j][i] = rmq[j][i - 1];
}
}
}
}
int main()
{
freopen("lca.in", "r", stdin);
freopen("lca.out", "w", stdout);
citire();
construireEuler();
construireRmq();
int l = euler.size();
for(int k = 0; k < m; k++)
{
int tmp1, tmp2;
scanf("%d %d", &tmp1, &tmp2);
tmp1--;
tmp2--;
int poz1 = firstAparition[tmp1];
int poz2 = firstAparition[tmp2];
if(poz2 < poz1)
{
swap(poz1, poz2);
}
int lg = log2(poz2 - poz1 + 1);
tmp2 = euler[rmq[poz1][lg]].first;
int tmp3 = euler[rmq[poz2 - ((1 << lg)) + 1][lg]].first;
if(tmp2 < tmp3)
{
tmp1 = rmq[poz1][lg];
}
else
{
tmp1 = rmq[poz2 - ((1 << lg)) + 1][lg];
}
printf("%d\n", euler[tmp1].second + 1);
}
return 0;
}