Pagini recente » Cod sursa (job #3288734) | Cod sursa (job #3288302)
#include <bits/stdc++.h>
using namespace std;
ifstream fin ( "lca.in" );
ofstream fout ( "lca.out" );
#define cin fin
#define cout fout
#define FR( a, b ) for( int a = 0; a < b; a ++ )
#define FOR( a, c, b ) for( int a = c; a < b ; a ++ )
#define PB push_back
#define F first
#define S second
typedef pair<int, int> pii;
const int Nmax = 1e5 + 5;
int cnt = 0;
bool processed[Nmax];
int adancime[Nmax], prima_aparitie[Nmax], parinte[Nmax], semnificativ[2 * Nmax];
pii rmq[18][2 * Nmax], euler[2 * Nmax];
vector<int> sons[Nmax];
void dfs( int nod ) {
adancime[nod] = adancime[parinte[nod]] + 1;
euler[++cnt].F = adancime[nod];
euler[cnt].S = nod;
if( prima_aparitie[nod] == 0 )
prima_aparitie[nod] = cnt;
FR( i, sons[nod].size() )
if( !processed[ sons[nod][i] ] )
dfs( sons[nod][i] );
processed[nod] = true;
if( nod != 1 ) {
euler[++cnt].F = adancime[parinte[nod]];
euler[cnt].S = parinte[nod];
}
}
int main()
{
int n, queries, u, v, l, r;
cin >> n >> queries;
FOR( i, 2, n + 1 ) {
cin >> u;
parinte[i] = u;
sons[u].PB( i );
}
semnificativ[1] = 0;
int val_crt = 1, nr_crt = 2, i;
while( nr_crt < 2 * n + 1 ) {
i = nr_crt;
while( i < 2 * nr_crt )
semnificativ[i++] = val_crt;
nr_crt *= 2;
val_crt ++;
}
FOR( i, 1, n + 1 )
cout << semnificativ[i] << " ";
cout << '\n';
adancime[0] = -1;
dfs( 1 );
FOR( i, 1, 2 * n ) {
rmq[0][i].F = euler[i].F;
rmq[0][i].S = euler[i].S;
}
for( i = 1; ( 1 << i ) < 2 * n; i ++ ) {
FOR( j, 1, 2 * n ) {
int k = ( 1 << (i-1) );
if( j + k < 2 * n ) {
if( rmq[i-1][j].F <= rmq[i-1][j + k].F ) {
rmq[i][j].F = rmq[i-1][j].F;
rmq[i][j].S = rmq[i-1][j].S;
} else {
rmq[i][j].F = rmq[i-1][j + k].F;
rmq[i][j].S = rmq[i-1][j + k].S;
}
}
else {
rmq[i][j].F = rmq[i-1][j].F;
rmq[i][j].S = rmq[i-1][j].S;
}
}
}
FR( i, queries ) {
cin >> u >> v;
l = prima_aparitie[u];
r = prima_aparitie[v];
if( l > r )
swap( l, r );
int len = semnificativ[r - l + 1];
if( rmq[len][l].F <= rmq[len][r - (1 << len) + 1 ].F )
cout << rmq[len][l].S << "\n";
else
cout << rmq[len][r - (1 << len) + 1].S << "\n";
}
return 0;
}