Pagini recente » Cod sursa (job #1553490) | Cod sursa (job #2852004) | Cod sursa (job #959019) | Cod sursa (job #1111792) | Cod sursa (job #3226567)
#include <iostream>
#include <fstream>
#include <vector>
#define NMAX 200001
#define INF 10000000
using namespace std;
int n, dpth;
int poz[NMAX];
struct str{
int ad, node;
} lvl[NMAX];
vector <int> sons[NMAX];
ifstream fin( "lca.in" );
ofstream fout( "lca.out" );
struct arbint {
int aint[4*NMAX];
void build( int node, int l, int r ) {
if( l == r ) {
aint[node] = l;
return;
}
int mijl = ( l + r ) / 2;
int lson = 2 * node;
int rson = 2 * node + 1;
build( lson, l, mijl );
build( rson, mijl + 1, r );
if( lvl[aint[lson]].ad < lvl[aint[rson]].ad )
aint[node] = aint[lson];
else
aint[node] = aint[rson];
}
int query( int node, int l, int r, int ql, int qr ) {
if( l >= ql && r <= qr )
return aint[node];
int rez = NMAX, mini = INF;
int mijl = ( l + r ) / 2;
int lson = 2 * node;
int rson = 2 * node + 1;
if( ql <= mijl ) {
int idk = query( lson, l, mijl, ql, qr );
if( lvl[idk].ad < mini ) {
mini = lvl[idk].ad;
rez = idk;
}
}
if( mijl < qr ) {
int idk = query( rson, mijl + 1, r, ql, qr );
if( lvl[idk].ad < mini ) {
mini = lvl[idk].ad;
rez = idk;
}
}
return rez;
}
} my_aint;
void dfs_euler( int node, int curr_lvl ) {
poz[node] = dpth;
lvl[poz[node]] = { curr_lvl, node };
dpth++; // pun node in parcurgerea euler
for( unsigned int i = 0; i < sons[node].size(); i++ ) {
int son = sons[node][i];
dfs_euler( son, curr_lvl + 1 );
lvl[dpth] = { curr_lvl, node };
dpth++; // pun node din nou in parcurgerea euler, dupa fiecare fiu
}
}
int main() {
int parinte, q, x, y;
fin >> n >> q;
for( int i = 2; i <= n; i++ ) {
fin >> parinte;
sons[parinte].push_back( i );
}
for( int i = 0; i <= 2 * n; i++ )
lvl[i].ad = INF;
dpth = 1;
dfs_euler( 1, 1 );
my_aint.build( 1, 1, dpth );
for( ; q; q-- ) {
fin >> x >> y;
if( poz[x] > poz[y] )
swap( x, y );
fout << lvl[my_aint.query( 1, 1, dpth, poz[x], poz[y] )].node << '\n';
}
return 0;
}