Pagini recente » Cod sursa (job #236863) | Cod sursa (job #1211230) | Cod sursa (job #1598675) | Cod sursa (job #1003300) | Cod sursa (job #2803407)
#include <iostream>
#include <fstream>
#include <bits/stdc++.h>
using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
const int NMAX=300000;
const int LGMAX=20;
/// adia[i] = lista de vecini ai lui i
vector <int> adia[NMAX];
int h[NMAX];
//int val_hash[NMAX];
//int sp[NMAX];
//int val_nod[NMAX];
/// suma hash 1,2..N
//int target_sum;
//mt19937 rnd(time(0));
/// stramos[p][i]= al 2^p -lea stramos al lui i
/// stramos [0][i]=tatal lui i
/// stramos [2][i] = tatal tatalui tatalui tatalui lui i
/// stramos[p][i]=stramos[p-1][ stramos[p-1][i] ]
int stramos[LGMAX][NMAX];
void Dfs(int nod, int t){
//sp[nod]=sp[tata]+val_hash[val_nod[nod]];
stramos[0][nod]=t;
for(int i=1; i<=LGMAX; i++)
stramos[i][nod]=stramos[i-1][stramos[i-1][nod]];
h[nod]=1+h[t];
//cout<<"Am ajuns in nodul "<<nod<<" din "<<t<<'\n';
for( auto i: adia[nod] ){
if( i!=t )
Dfs(i, nod);
}
}
/*ridica un nod cu x noduri mai sus in arbore*/
void Up( int &nod, int x )
{
for(int b=0; b<LGMAX; b++){
if( x&(1<<b) )
nod=stramos[b][nod];
}
}
/*returneaza cel mai jos stramos comun a 2 noduri diferite*/
int Lca(int a, int b){
if( h[a]<h[b] )
swap(a, b);
Up(a, h[a]-h[b]);
//out<<"alo";
/// daca initial unul e un stramos al celuilalt
if( a==b ){
//cout<<" stramos al celuilalt ";
return a;
}
/// ne mutam in sus cat timp nu dam de un stramos comun
for(int i=LGMAX-1; i>=0; i--){
if(stramos[i][a]!=stramos[i][b])
a=stramos[i][a], b=stramos[i][b];
}
return stramos[0][a]; /// fiul
}
/// arbore cu sume partiale sp
/// a si b stramos
/// s[a]+...+s[b] = sp[a] - sp[ tata[b] ]
/// b nu este neaparat stramos:
/// sp[a]+sp[b]-sp[LCA]-sp[tatal LCA]
/*
void Check(int a, int b){
int lca=Lca(a, b);
int sum_lant=sp[a]+sp[b]-sp[lca]-sp[stramos[0][lca]];
return sum_lant==target_sum;
} */
int main()
{
int n, m;
in>>n>>m;
/**
for(int i=0; i<NMAX; i++){
val_hash[i]=rnd();
}
for(int i=1; i<=M; i++){
target_sum+=val_hash[i];
} **/
for(int i=1; i<=n-1; i++){
int a;
in>>a;
stramos[0][i+1]=a;
//Dfs( i+1, a );
//adia[a].push_back(a+1);
//adia[a+1].push_back(a);
}
for(int i=1; i<=n-1; i++){
Dfs( i+1, stramos[0][i+1] );
}
int x, y;
for(int i=1; i<=m; i++){
in>>x>>y;
out<<Lca( x, y )<<'\n';
}
return 0;
}