Pagini recente » Cod sursa (job #2781012) | Cod sursa (job #666666) | Cod sursa (job #712670) | Cod sursa (job #751670) | Cod sursa (job #594309)
Cod sursa(job #594309)
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
ifstream fin ("lca.in");
ofstream fout ("lca.out");
vector <unsigned long> G[100005], EulerianF, Level;
unsigned long N, First[100005], Log2[100005], RMQ[20][200010];
void DFS (unsigned long X, unsigned long L)
{
unsigned long i;
First[X]=EulerianF.size ();
EulerianF.push_back (X);
Level.push_back (L);
for (i=0; i<G[X].size (); ++i)
{
DFS (G[X][i], L+1);
EulerianF.push_back (X);
Level.push_back (L);
}
}
inline void BuildEulerianF ()
{
Level.push_back (0);
EulerianF.push_back (0);
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<EulerianF.size (); ++i)
{
RMQ[0][i]=i;
if (i>1)
{
Log2[i]=Log2[i/2]+1;
}
}
for (i=1; i<=Log2[EulerianF.size ()-1]; ++i)
{
n=EulerianF.size ()-(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 EulerianF[MinRMQ (RMQ[Log2[D]][a], RMQ[Log2[D]][a+D-(1<<Log2[D])])];
}
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 << Query (Min (First[QA], First[QB]), Max (First[QA], First[QB])) << "\n";
}
}
fin.close ();
fout.close ();
return 0;
}