Pagini recente » Borderou de evaluare (job #2104782) | Borderou de evaluare (job #2047256) | Borderou de evaluare (job #1005279) | Borderou de evaluare (job #3044077) | Cod sursa (job #3274264)
#include <fstream>
#include <iostream>
#include <vector>
using namespace std;
struct elem{
int x, nivel;
};
int rmq[300005][20], logar[300005], first[100005];
vector <int> v[100005];
vector <elem> euler;
void dfs( int x, int nivel ){
int i;
euler.push_back( { x, nivel } );
first[x] = euler.size() - 1;
for( i = 0; i < v[x].size(); i++ ){
dfs( v[x][i], nivel + 1 );
euler.push_back( { x, nivel } );
}
}
int lca(int x, int y){
int l, a, b;
//cout << x << ' ' << y << ' ';
x = first[x];
y = first[y];
if( x > y ){
swap( x, y );
}
//cout << x << ' ' << y << '\n';
l = logar[y - x + 1];
a = rmq[x][l];
b = rmq[y - ( 1 << l ) + 1][l];
if( euler[a].nivel < euler[b].nivel ){
return euler[a].x;
}
return euler[b].x;
}
int main(){
int n, m, i, j, x, y;
ifstream fin( "lca.in" );
ofstream fout( "lca.out" );
fin >> n >> m;
for( i = 2; i <= n; i++ ){
fin >> x;
v[x].push_back( i );
}
dfs( 1, 0 );
for( i = 0; i < euler.size(); i++ ){
rmq[i][0] = i;
}
for( i = 1; ( 1 << i ) <= euler.size(); i++ ){
for( j = 0; j + ( 1 << i ) - 1 < euler.size(); j++ ){
x = rmq[j][i - 1];
y = rmq[j + ( 1 << ( i - 1 ) )][i - 1];
if( euler[x].nivel < euler[y].nivel ){
rmq[j][i] = x;
}
else{
rmq[j][i] = y;
}
//cout << j << ' ' << ( 1 << i ) << ' ' << euler[rmq[j][i]].x << '\n';
}
}
logar[0] = logar[1] = 0;
for( i = 2; i < euler.size(); i++ ){
logar[i] = logar[i / 2] + 1;
//cout << euler[i].x << ' ' << euler[i].nivel << '\n';
}
for( i = 0; i < m; i++ ){
fin >> x >> y;
fout << lca( x, y ) << '\n';
}
return 0;
}