Pagini recente » Cod sursa (job #2394241) | Cod sursa (job #179262) | Cod sursa (job #2998828) | Cod sursa (job #1314913) | Cod sursa (job #2401646)
#include <iostream>
#include <fstream>
#include <vector>
#include <bitset>
#include <cstring>
#define DN 100005
#define per pair<int,int>
#define pb push_back
#define next_nod list[nod][i]
#define un unsigned
#define mp make_pair
#define DNN 5*DN
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");
int t[DN],deep[DN],sz,ap[DN]; /// rmq[30][DNN];
vector< int > list[DN];
bitset< DN > viz;
int rmq[21][DNN],val[21][DNN];
/// in rmq[][] retin valoarea minima de pe liniarizarea euler arborelui
/// in nod[][] retin nodul cu aceasta valoare
void dfs(int nod,int down)
{
viz[nod]=true;
deep[nod]=down;
rmq[0][++sz]=deep[nod];
val[0][sz]=nod;
ap[nod]=sz; /// prima aparitie
for(un int i=0;i<list[nod].size();++i){
if( !viz[ next_nod ] ){
dfs(next_nod , 1 + down);
rmq[0][++sz]=deep[nod];
val[0][sz]=nod;
}
}
return;
}
void gen()
{
for(int pow=1;pow<=20;++pow)
for(int i=1; i + (1<<(pow-1)) <= sz ;++i){
int first_part = rmq [ pow - 1 ][ i ];
int second_part = rmq [ pow - 1 ][ i + (1<<(pow-1)) ];
if( first_part < second_part ){
rmq[ pow ][ i ] = first_part ;
val[ pow ][ i ] = val [ pow - 1 ][ i ];
}
else{
rmq[ pow ][ i ] = second_part;
val[ pow ][ i ] = val[ pow-1 ][ i + (1<<(pow-1))];
}
}
}
int solve(int a,int b)
{
int pow=0;
a = ap[a]; /// prima pozitie in care apare in euler
b = ap[b];
if(a>b)
swap(a,b);
for(; a + (1<<pow) <=b ;++pow); if(pow) --pow;
int left = rmq [ pow ][ a ];
int right = rmq[ pow ][ b - (1<<pow) + 1];
if(left<right)
return val [ pow ][ a ];
return val[pow][ b - (1<<pow) + 1];
}
int main()
{
int n,m;
memset(rmq,0x3f3f3f3f,sizeof(rmq));
f>>n>>m;
for(int i=2;i<=n;++i){
f>>t[i];
list[ t[i] ].pb( i );
}
dfs(1,1);
gen();
for(;m--;)
{
int a,b;
f>>a>>b;
g<<solve(a,b)<<"\n";
}
return 0;
}