Pagini recente » Cod sursa (job #638037) | Cod sursa (job #2194711) | Cod sursa (job #824588) | Cod sursa (job #2962567) | Cod sursa (job #555527)
Cod sursa(job #555527)
#include<fstream>
#include<vector>
#define inf "lca.in"
#define outf "lca.out"
#define NMax 100100
using namespace std;
fstream f(inf,ios::in),g(outf,ios::out);
int N, M;
int L[2*NMax], E[2*NMax], First[NMax], K, viz[NMax];
int rmq[2*NMax][18], lg[2*NMax];
vector<int> G[NMax];
void DFS(int u, int level)
{
E[++K] = u; L[K] = level;
First[u] = K; viz[u] = 1;
for(int i=0; i<G[u].size(); i++)
{
int v = G[u][i];
if( !viz[v] )
{
DFS(v, level+1);
E[++K] = u; L[K] = level;
}
}
}
void RMQ()
{
for(int i=2; i<=K; i++) lg[i] = lg[i/2] + 1;
for(int i=1; i<=K; i++) rmq[i][0] = i;
for(int i=1; (1<<i)<=K; i++)
for(int j=1; j + (1<<i) - 1 <= K ; j++)
{
int l = 1<<(i-1);
rmq[j][i] = rmq[j][i-1];
if( L[ rmq[ j+l ][i-1] ] < L[ rmq[j][i] ] ) rmq[j][i] = rmq[ j+l ][i-1];
}
}
inline int min(int a,int b) { return ( a<b ? a : b ); }
inline int lca(int u, int v)
{
int a = First[u], b = First[v];
if( a>b ) swap(a,b);
int l = b-a+1; int k = lg[l];
int dif = l - (1<<k);
int sol = rmq[a][k];
if( L[ rmq[a+dif][k] ] < L[sol] ) sol = rmq[a+dif][k];
return E[sol];
}
void read()
{
f>>N>>M; int a, u, v;
for(int i=2; i<=N; i++)
{
f>>a;
G[i].push_back(a); G[a].push_back(i);
}
DFS(1,0);
RMQ();
for(int i=1; i<=M; i++)
{
f>>u>>v;
g<< lca(u,v) <<"\n";
}
}
int main()
{
read();
f.close(); g.close();
return 0;
}