Pagini recente » Cod sursa (job #1823457) | Cod sursa (job #1810953)
#include <stdio.h>
#include <queue>
using namespace std;
FILE *fin = fopen("lca.in", "r");
FILE *fout = fopen("lca.out", "w");
int minim(int a, int b)
{
if(a <= b) return a;
return b;
}
int cmmp(int a, int b)
{
int incadrez = b-a+1;
int putere = 1;
while(2*putere<=incadrez)
{
putere*=2;
}
return putere;
}
int coef(int a, int b)
{
int incadrez = b-a+1;
int putere = 1;
int rand = 1;
while(2*putere<=incadrez)
{
rand++;
putere*=2;
}
return rand;
}
int corespondent[100001];
int n, m,q,nod1,nod2;
int answer[17][210001];
int invers[100001];
char vizitat[100001];
int cnt=1;
int nod;
int prima[210001];
vector <int> fii[100001];
vector <int> pEuler;
void euler(int nod)
{
pEuler.push_back(corespondent[nod]);
for(auto m : fii[nod])
{
euler(m);
pEuler.push_back(corespondent[nod]);
}
}
int main()
{
fscanf(fin, "%d%d", &n, &q);
for(int i = 1; i <= n-1; i ++)
{
fscanf(fin, "%d", &nod);
fii[nod].push_back(i+1);
}
queue <int> frontiera;
int start = 1;
frontiera.push(start);
while(!frontiera.empty())
{
nod=frontiera.front();
frontiera.pop();
corespondent[nod]=cnt;
invers[cnt]=nod;
cnt++;
vizitat[nod]=1;
for(auto m : fii[nod])
{
if(vizitat[m] == 0)
{
vizitat[m]=1;
frontiera.push(m);
}
}
}
euler(1);
cnt = 1;
for(auto m : pEuler)
{
if(prima[m]==0) prima[m]=cnt;
answer[1][cnt]=m;
cnt++;
}
cnt--;
m = cnt;
int ad=1;
for(int i = 2; i <= 17 ;i++)
{
for(int j = 1; j <= m; j++)
{
if(j+ad <= m)
{
answer[i][j]=minim(answer[i-1][j], answer[i-1][j+ad]);
}
}
ad*=2;
}
for(int i = 1; i <= q; i++)
{
fscanf(fin, "%d%d", &nod1, &nod2);
int x=prima[corespondent[nod1]];
int y=prima[corespondent[nod2]];
int diametru = cmmp(x , y);
int coeficient = coef(x, y);
fprintf(fout, "%d\n", invers[minim(answer[coeficient][x], answer[coeficient][y-diametru+1])]);
}
return 0;
}