Pagini recente » Cod sursa (job #3280553) | Cod sursa (job #2698668) | Cod sursa (job #2904432) | Cod sursa (job #2748690) | Cod sursa (job #2741067)
#include <fstream>
#include <vector>
using namespace std;
ifstream fin( "lca.in" );
ofstream fout( "lca.out" );
const int MaxN = 100003;
const int MaxLog = 20;
vector<int> tree[MaxN];
vector<int> euler;
vector<int> level;
int viz[MaxN], pos[MaxN], lg[2 * MaxN];
struct { int val, pos; } minr[MaxLog][2 * MaxN];
void buildEuler( int node, int dep ) {
viz[node] = 1;
euler.push_back( node );
level.push_back( dep );
for ( int i = 0; i < tree[node].size(); ++i ) {
if ( !viz[tree[node][i]] ) {
buildEuler( tree[node][i], dep + 1 );
}
euler.push_back( node );
level.push_back( dep );
}
}
int LCA( int x, int y ) {
int l = min( pos[x], pos[y] ), r = max( pos[x], pos[y] );
int k = lg[r - l + 1];
if ( minr[k][l].val < minr[k][r - (1 << k) + 1].val ) {
return euler[minr[k][l].pos];
}
return euler[minr[k][r - (1 << k) + 1].pos];
}
int main() {
int n, k, f, u, v;
fin >> n >> k;
pos[1] = -1;
for ( int i = 2; i <= n; ++i ) {
fin >> f;
tree[f].push_back( i );
pos[i] = -1;
}
buildEuler( 1, 0 );
for ( int i = 0; i < euler.size(); ++i ) {
if ( pos[euler[i]] == -1 ) {
pos[euler[i]] = i;
}
}
n = euler.size();
for ( int i = 2; i <= n; ++i ) {
lg[i] = lg[i >> 1] + 1;
}
for ( int i = 0; i < n; ++i ) {
minr[0][i].val = level[i];
minr[0][i].pos = i;
}
for ( int i = 1; i <= lg[n]; ++i ) {
for ( int j = 0; j + (1 << (i - 1)) < n; ++j ) {
if ( minr[i - 1][j].val > minr[i - 1][j + (1 << (i - 1))].val ) {
minr[i][j] = minr[i - 1][j + (1 << (i - 1))];
} else {
minr[i][j] = minr[i - 1][j];
}
}
}
while ( k-- ) {
fin >> u >> v;
fout << LCA( u, v ) << "\n";
}
fin.close();
fout.close();
return 0;
}