Pagini recente » Cod sursa (job #3032340) | Cod sursa (job #262104) | Cod sursa (job #272298) | Cod sursa (job #317812) | Cod sursa (job #1840140)
// Patrick Sava
// Expected : 100
#include <bits/stdc++.h>
using namespace std ;
#define FORN(a,b,c) for(int a=b;a<=c;++a)
#define FORNBACK(a,b,c) for (int a=b;a>=c;--a)
#define mp make_pair
#define pb push_back
const int MAX = 1e5 + 14 ;
const int LG = 7 ;
vector < int > gr [ MAX ], lant [ MAX ] ;
int nrlant ;
int lantdenod[MAX] ;
int poz [MAX] ;
int sub [MAX] ;
int tata [MAX] ;
int dp [LG] [MAX] ;
void dfs ( int nod )
{
sub [nod] = 1 ;
int where = 0 ;
for ( auto x : gr [nod] ) {
tata [x] = nod ;
dfs (x);
sub [nod] += sub [x] ;
if (sub [x] > sub [where] ) {
where = x ;
}
}
if (gr[nod].size()==0){
++ nrlant ;
lant [nrlant].pb(nod) ;
poz [nod] = lant [nrlant].size() - 1;
lantdenod [nod] = nrlant ;
}
else {
lant [lantdenod[where]].pb(nod) ;
poz [nod] = lant [lantdenod[where]].size() - 1 ;
lantdenod [nod] = lantdenod[where] ;
}
}
int sz ;
int lvl [MAX] ;
int lg [MAX] ;
int getmax ;
void dfs2 ( int nod )
{
if ( poz [nod] == lant [lantdenod[nod]].size() - 1 ) {
lvl [lantdenod[nod]] = sz ;
++ sz ;
getmax = max ( sz , getmax ) ;
}
for ( auto x : gr [nod] ) {
dfs2(x) ;
}
if ( poz [nod] == lant [lantdenod[nod]].size() - 1 ) {
-- sz ;
}
}
int lca ( int x , int y )
{
if ( lvl[lantdenod [x]] < lvl [lantdenod[y]] ) {
swap (x,y) ;
}
int dif = lvl[lantdenod [x]] - lvl [lantdenod[y]] ;
for ( int put = lg [dif] + 1 ; put >= 0 ; -- put ) {
if ( dif & ( 1 << put ) ) {
x = dp [put][x] ;
}
}
if ( lantdenod [x] == lantdenod [y] ){
if (poz[x] > poz [y]) {
return x ;
}
return y ;
}
for ( int put = lg [lvl[lantdenod[x]]] + 1 ; put >= 0 ; -- put ){
if ( dp [put][x] and dp [put][y] and lantdenod[dp [put] [x]] != lantdenod[dp [put] [y]] ) {
x = dp [put] [x] ;
y = dp [put] [y] ;
}
}
if ( lantdenod [x] == lantdenod [y] ){
if (poz[x] > poz [y]) {
return x ;
}
return y ;
}
if ( poz [dp[0][x]] > poz [dp[0][y]] ) {
return dp[0][x] ;
}
return dp [0][y] ;
}
int readInt () {
bool minus = false;
int result = 0;
char ch;
ch = getchar();
while (true) {
if (ch == '-') break;
if (ch >= '0' && ch <= '9') break;
ch = getchar();
}
if (ch == '-') minus = true; else result = ch-'0';
while (true) {
ch = getchar();
if (ch < '0' || ch > '9') break;
result = result*10 + (ch - '0');
}
if (minus)
return -result;
else
return result;
}
int main ()
{
freopen ("lca.in", "r", stdin) ;
freopen ("lca.out" ,"w", stdout) ;
int n, m;
n = readInt() ;
m = readInt() ;
FORN ( i , 2 , n ) {
int x ;
x = readInt() ;
gr [x].pb (i) ;
lg [i] = lg [i >> 1] + 1 ;
}
dfs (1) ;
dfs2 (1) ;
FORN ( i , 1 , n ) {
dp [0] [i] = tata [ lant [ lantdenod [i] ].back() ] ;
}
for ( int j = 1 ; j <= lg [getmax] + 1 ; ++ j ) {
for ( int i = 1 ; i <= n ; ++ i ) {
dp [j] [i] = dp [j-1] [dp[j-1][i]] ;
}
}
while (m--)
{
int x,y ;
x = readInt() ;
y = readInt() ;
printf ("%d\n" , lca(x,y)) ;
}
return 0 ;
}