Pagini recente » Cod sursa (job #2303348) | Cod sursa (job #1353923) | Cod sursa (job #1106305) | Cod sursa (job #111273) | Cod sursa (job #404087)
Cod sursa(job #404087)
#include <fstream>
#include <vector>
#define NMAX 100100
#define LGMAX 20
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
int N, M, Min[5+LGMAX][LGMAX*NMAX], Pos[NMAX], EU[LGMAX*NMAX], LG[LGMAX*NMAX], Depth[LGMAX*NMAX], EULen, PMin[5+LGMAX][LGMAX*NMAX];
vector<int> C[NMAX];
void Citire(void)
{
int i, x;
fin >>N >>M;
for (i = 2; i <= N; i++)
{
fin >>x;
C[x].push_back(i);
}
}
void DFS(int Nod, int Nivel)
{
EU[++EULen] = Nod;
Depth[EULen] = Nivel;
Pos[Nod] = EULen;
for (int i = 0; i < C[Nod].size(); i++)
{
DFS(C[Nod][i], Nivel+1);
EU[++EULen] = Nod;
Depth[EULen] = Nivel;
}
}
void CalcLG(void)
{
int i;
for (i = 2; i <= EULen; i++)
LG[i] = LG[i/2] + 1;
}
int minim(int a, int b)
{
if (a < b) return a;
else return b;
}
void GenereazaMin(void)
{
int i, j;
for (i = 1; i <= EULen; i++)
Min[0][i] = Depth[i], PMin[0][i] = EU[i];
for (j = 1; j <= LG[EULen]; j++)
for (i = 1; i <= EULen; i++)
Min[j][i] = NMAX;
for (j = 1; j <= LG[EULen]; j++)
for (i = 1; i <= EULen - (1 << j) + 1; i++)
{
if (Min[j-1][i] < Min[j-1][i + (1 << (j - 1))])
{
Min[j][i] = Min[j-1][i];
PMin[j][i] = PMin[j-1][i];
}
else
{
Min[j][i] = Min[j-1][i + (1 << (j - 1))];
PMin[j][i] = PMin[j-1][i + (1 << (j - 1))];
}
}
}
void AfiseazaRezultate(void)
{
int i, a, b;
for (i = 1; i <= M; i++)
{
fin >>a >>b;
a = Pos[a];
b = Pos[b];
if (a > b) swap(a,b);
if (Min[LG[b-a+1]][a] < Min[LG[b-a+1]][b + 1 - (1 << LG[b-a+1])])
fout << PMin[LG[b-a+1]][a];
else
fout << PMin[LG[b-a+1]][b + 1 - (1 << LG[b-a+1])];
fout <<'\n';
}
fin.close();
fout.close();
}
int main()
{
Citire();
DFS(1,0);
CalcLG();
GenereazaMin();
AfiseazaRezultate();
return 0;
}