Pagini recente » Istoria paginii utilizator/best4him | Cod sursa (job #983706) | Rating Stefan Predescu (Fpre) | Cod sursa (job #1785540) | Cod sursa (job #2890969)
//LCA
#include <fstream>
#include <vector>
using namespace std;
const int MAX = 100014;
const int LOGMAX = 22;
struct st {
int nivel , nod ;
};
st q[ MAX << 1];
vector < int > gr[MAX];
int now , first [MAX] , R[LOGMAX][MAX << 2] , log[MAX << 1] ;
void dfs(int nod, int lvl){
++ now ;
q [now].nivel = lvl ;
q [now].nod = nod ;
first[nod] = now ;
for ( auto x : gr[nod] )
{
dfs (x, lvl + 1) ;
++ now ;
q [now].nivel = lvl ;
q [now].nod = nod ;
}
}
void RMQ ( int n )
{
log[1] = 0 ;
for (int i = 2 ; i <= n ; ++ i )
log[i] = log[i>>1] + 1 ;
for (int i = 1 ; i <= n ; ++ i)
R [0][i] = i ;
for (int i = 1 ; (1 << i) <= n ; ++ i)
for (int j = 1 ; j <= n - (1<<i) + 1 ; ++ j){
int l = 1 << ( i - 1 ) ;
R[i][j] = R[i-1][j] ;
if ( q[R[i][j]].nivel > q[R[i-1][j+l]].nivel )
R[i][j] = R[i-1][j+l] ;
}
}
int lca(int x ,int y)
{
int a = first [ x ] ;
int b = first [ y ] ;
if ( a > b )
swap ( a , b ) ;
int diff = b - a + 1 ;
int lg = log [ diff ] ;
int sol = R [ lg ] [ a ] ;
int sh = diff - (1 << lg) ;
if ( q [ sol ].nivel > q[ R [ lg ] [ a + sh ] ].nivel )
sol = R [ lg ] [ a + sh ];
return q [ sol ].nod ;
}
int main( )
{
ifstream fin("lca.in");
ofstream fout("lca.out");
int n , m ;
fin >> n >> m ;
for (int i = 2 ; i <= n ; ++ i){
int x ;
fin >> x;
gr[x].push_back(i) ;
}
dfs (1, 0) ;
RMQ (now) ;
while (m--){
int x, y ;
fin >> x >> y ;
fout << lca(x ,y) << '\n' ;
}
return 0;
}