Pagini recente » Cod sursa (job #976133) | Cod sursa (job #2482019) | Cod sursa (job #1044195) | Cod sursa (job #990622) | Cod sursa (job #594341)
Cod sursa(job #594341)
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
ifstream fin ("lca.in");
ofstream fout ("lca.out");
vector <unsigned long> G[100005];
unsigned long N, First[100005], Log2[100005], RMQ[20][200010], EulerianF[200010], Level[200010], LEF;
void DFS (unsigned long X, unsigned long L)
{
unsigned long i;
EulerianF[++LEF]=X;
Level[LEF]=X;
First[X]=LEF;
for (i=0; i<G[X].size (); ++i)
{
DFS (G[X][i], L+1);
EulerianF[++LEF]=X;;
Level[LEF]=X;
}
}
inline void BuildEulerianF ()
{
DFS (1, 0);
}
inline unsigned long Min (unsigned long a, unsigned long b)
{
if (a<b)
{
return a;
}
return b;
}
inline unsigned long Max (unsigned long a, unsigned long b)
{
if (a>b)
{
return a;
}
return b;
}
inline unsigned long MinRMQ (unsigned long a, unsigned long b)
{
if (Level[a]<Level[b])
{
return a;
}
return b;
}
void BuildRMQ ()
{
unsigned long i, j, Putere2, n;
Log2[1]=0;
for (i=1; i<=LEF; ++i)
{
RMQ[0][i]=i;
if (i>1)
{
Log2[i]=Log2[i/2]+1;
}
}
for (i=1; i<=Log2[LEF]; ++i)
{
n=LEF-(1<<i);
Putere2=(1<<(i-1));
for (j=1; j<=n; j++)
{
RMQ[i][j]=MinRMQ (RMQ[i-1][j], RMQ[i-1][j+Putere2]);
}
}
}
inline unsigned long Query (unsigned long a, unsigned long b)
{
unsigned long D;
D=b-a+1;
return MinRMQ (RMQ[Log2[D]][a], RMQ[Log2[D]][a+D-(1<<Log2[D])]);
}
inline unsigned long LCA (unsigned long a, unsigned long b)
{
unsigned long PozitieEF;
PozitieEF = Query (Min (First[a], First[b]), Max (First[a], First[b]));
return EulerianF [PozitieEF];
}
int main()
{
unsigned long QA, QB, M, i, X;
fin >> N >> M;
for (i=2; i<=N; ++i)
{
fin >> X;
G[X].push_back (i);
}
BuildEulerianF ();
BuildRMQ ();
for (; M>0; --M)
{
fin >> QA >> QB;
if (QA==QB)
{
fout << QA << "\n";
}
else
{
fout << LCA (QA, QB) << "\n";
}
}
fin.close ();
fout.close ();
return 0;
}