Pagini recente » Cod sursa (job #1057091) | Cod sursa (job #603792) | Teoria jocurilor: numerele Sprague Grundy | Cod sursa (job #2837048) | Cod sursa (job #2538830)
#include <fstream>
#include <vector>
#define pb push_back
const int MAXN = 100000;
using namespace std;
ifstream cin( "lca.in" );
ofstream cout( "lca.out" );
int n, m, q;
vector<int> fii[MAXN+1];
struct Node
{
int nod, nivel;
};
vector<Node> euler;
int first[MAXN+1];
int log2[3*MAXN+1];
Node rmq[3*MAXN+1][20];
void parcurgereEuler( int sursa, int lvl )
{
euler.pb({sursa,lvl});
first[sursa]=euler.size();
for( auto it:fii[sursa] )
{
parcurgereEuler(it,lvl+1);
euler.pb({sursa,lvl});
}
}
Node minim( Node a, Node b )
{
if( b.nivel<a.nivel )
a=b;
return a;
}
int main()
{
cin>>n>>q;
for( int i=2;i<=n;i++ )
{
int k; cin>>k;
fii[k].pb(i);
}
parcurgereEuler(1,0);
m=euler.size();
rmq[1][0]=euler[0];
for( int i=2;i<=m;i++ )
{
log2[i]=log2[i/2]+1;
rmq[i][0]=euler[i-1];
}
for( int j=1;(1<<j)<=m;j++ )
for( int i=1;i<=m-(1<<j)+1;i++ )
{
int l=(1<<(j-1));
rmq[i][j]=minim(rmq[i][j-1],rmq[i+l][j-1]);
}
while( q-- )
{
int x, y; cin>>x>>y;
x=first[x];
y=first[y];
if( x>y )
{
int aux=x;
x=y;
y=aux;
}
int l=log2[y-x+1];
cout<<minim(rmq[x][l],rmq[y-(1<<l)+1][l]).nod<<"\n";
}
return 0;
}