Pagini recente » Cod sursa (job #989561) | Cod sursa (job #1410209) | Cod sursa (job #734180) | Cod sursa (job #1825454) | Cod sursa (job #2533604)
#include <iostream>
#include <fstream>
#include <vector>
#include <map>
#include <cmath>
const int MAXN = 100000 * 2 + 1;
const int MAXLOG = 17;
using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
vector<int>graf[MAXN];
struct punct{
int nod,h;
};
int n,euler[MAXN],index,inaltime[MAXN],pozitie[MAXN];
punct dp[MAXLOG][MAXN];
void dfs(int nod,int anterior = -1){
euler[++index] = nod;
for(auto vecin : graf[nod]){
if(vecin != anterior){
inaltime[vecin] = inaltime[nod] + 1;
dfs(vecin,nod);
euler[++index] = nod;
}
}
}
punct min(punct a,punct b){
if(a.h < b.h)
return a;
return b;
}
int main()
{
int intrebari;
in>>n>>intrebari;
for(int i = 2; i <= n; i++){
int tata;
in>>tata;
graf[i].push_back(tata);
graf[tata].push_back(i);
}
inaltime[1] = 1;
dfs(1);
// cout<<"Parcurgere Euler : ";
// for(int i = 1; i <= index; i++)
// cout<<i<<" ";
// cout<<endl;
// cout<<"Parcurgere Euler : ";
// for(int i = 1; i <= index; i++)
// cout<<euler[i]<<" ";
// cout<<endl;
// cout<<"Inaltime nod : ";
// for(int i = 1; i <= index; i++)
// cout<<inaltime[euler[i]]<<" ";
// cout<<endl;
for(int i = 1; i <= index; i++){
dp[0][i] = punct{euler[i],inaltime[euler[i]]};
if(!pozitie[euler[i]])
pozitie[euler[i]] = i;
}
for(int put = 1; put <= MAXLOG - 1; put++){
for(int i = 1; i <= index; i++){
/// i + 2 ^ put = [i,i + 2 ^ (put - 1)] + [i + 2^(put-1) + 2^(put - 1),i + 2^put]
dp[put][i] = min(dp[put - 1][i],dp[put - 1][i + (1<<(put - 1))]);
}
}
for(int i = 1; i <= intrebari; i++){
int x,y;
in>>x>>y;
int pozx = pozitie[x],pozy = pozitie[y];
if(pozx > pozy)
swap(pozx,pozy);
int lung = pozy - pozx;
int log_lung = log2(lung);
out<<min(dp[log_lung][pozx],dp[log_lung][pozy - (1<<log_lung)]).nod<<"\n";
}
return 0;
}