Pagini recente » Cod sursa (job #3197596) | Cod sursa (job #753023) | Cod sursa (job #2878496) | Cod sursa (job #1899917) | Cod sursa (job #594303)
Cod sursa(job #594303)
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
ifstream fin ("lca.in");
ofstream fout ("lca.out");
vector <unsigned long> G[100005], EulerianF;
unsigned long N, First[100005], Log2[100005], RMQ[20][200010], Level[100005];
bool V[100005];
void DFS (unsigned long X, unsigned long L)
{
unsigned long i;
V[X]=true;
First[X]=EulerianF.size ()-1;
EulerianF.push_back (X);
Level[X]=L;;
for (i=0; i<G[X].size (); ++i)
{
if (V[G[X][i]]==false)
{
DFS (G[X][i], L+1);
EulerianF.push_back (X);
}
}
}
inline void BuildEulerianF ()
{
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]=EulerianF[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-Log2[b-a+1]+1;
return MinRMQ (RMQ[Log2[b-a-1]][a], RMQ[Log2[b-a-1]][a+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);
G[i].push_back (X);
}
BuildEulerianF ();
BuildRMQ ();
for (; M>0; --M)
{
fin >> QA >> QB;
fout << Query (First[Min (QA, QB)], First[Max (QA, QB)]) << "\n";
}
fin.close ();
fout.close ();
return 0;
}