Pagini recente » Cod sursa (job #119146) | Cod sursa (job #2528996) | Cod sursa (job #380350) | Cod sursa (job #2357511) | Cod sursa (job #3231868)
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
int t[100001];
vector<int> fii[100001];
int n, m, pozInE[100001], E[1700000][2];
int poz, minim[100][25000], minim_pos[100][25000];
void ConstrEuler(int nod, int adancime)
{
if(pozInE[nod] == 0) pozInE[nod] = poz;
E[poz][0] = nod;
E[poz][1] = adancime;
poz++;
for(auto y : fii[nod])
{
ConstrEuler(y, adancime + 1);
E[poz][0] = nod;
E[poz][1] = adancime;
poz++;
}
}
int MinimInterval(int s, int d)
{
if(s == d)
return minim[s][0];
int k = 0;
while((1<<k)+s <= d) k++;
k--;
if((1<<k)+s < d)
return min(minim[s][k], MinimInterval(s+(1<<k), d));
else
return minim[s][k+1];
}
int PozMinim(int s, int d)
{
int k = 0;
while((1<<k)+s <= d) k++;
k--;
if (s+(1<<k) < d)
return (minim[s][k] < MinimInterval(s+(1<<k), d) ? minim_pos[s][k] : PozMinim(s+(1<<k), d));
else
return minim_pos[s][k+1];
}
int main()
{
int i, k, interval;
fin >> n >> m;
for(i = 2; i <= n; i++)
{
fin >> t[i];
fii[t[i]].push_back(i);
}
ConstrEuler(1,0);
for(i = 0; i < poz; i++)
{
minim[i][0] = E[i][1];
minim_pos[i][0] = i;
}
for(k = 1; k < n; k++)
{
for(i = 0; i < poz - (1 << (k - 1)); i++)
{
minim[i][k] = min(minim[i][k-1], minim[i+(1<<(k-1))][k-1]);
minim_pos[i][k] = (minim[i][k-1] <= minim[i+(1<<(k-1))][k-1] ? minim_pos[i][k-1] : minim_pos[i+(1<<(k-1))][k-1]);
}
}
for(interval = 1; interval <= m; interval++)
{
int x, y;
fin >> x >> y;
if (pozInE[x] > pozInE[y]) swap(x, y);
fout << E[PozMinim(pozInE[x], pozInE[y])][0] << '\n';
}
return 0;
}