Pagini recente » Cod sursa (job #1581959) | Cod sursa (job #1340895) | Cod sursa (job #290863) | Cod sursa (job #1605319) | Cod sursa (job #2099912)
#include <fstream>
#include <vector>
#include <cmath>
using namespace std;
ifstream cin ("lca.in");
ofstream cout ("lca.out");
vector < vector < int > > gr(100100);
vector < int > dad (100100);
vector < int > G (100100);
vector < int > lv (100100);
int rad = 0;
int cont = 0;
vector < vector < int > > chain(100100);
vector < int > CHAIN(100100);
vector < int > NR(100100);
vector < int > LV(100100);
void dfs (int root){
lv[root] = lv[dad[root]] + 1;
int MAX = 0;
int go = 0;
G[root] = 1;
for (auto &x : gr[root]){
dfs(x);
if (chain[CHAIN[x]].size() < rad && MAX < G[x]){
MAX = G[x];
go = x;
}
G[root] += G[x];
}
if (go == 0){
cont ++;
chain[cont].push_back(root);
CHAIN[root] = cont;
NR[root] = 0;
LV[cont] = lv[root];
}
else{
chain[CHAIN[go]].push_back(root);
CHAIN[root] = CHAIN[go];
NR[root] = chain[CHAIN[root]].size() - 1;
LV[CHAIN[root]] = lv[root];
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
//bucati de radical (HPD in mizerie)
int n , m;
cin>>n>>m;
rad = int(sqrt(n));
for (int i=2; i<=n; i++){
cin>>dad[i];
gr[dad[i]].push_back(i);
}
dfs(1);
/*cout<<cont<<'\n';
for (int i=1; i<=cont; i++){
for (auto &x : chain[i]){
cout<<x<<" ";
}
cout<<'\n';
}
cout<<'\n';*/
for (int i=1; i<=m; i++){
int x , y;
cin>>x>>y;
while (CHAIN[x] != CHAIN[y]){
if (LV[CHAIN[x]] > LV[CHAIN[y]]){
x = dad[chain[CHAIN[x]][chain[CHAIN[x]].size() - 1]];
}
else{
y = dad[chain[CHAIN[y]][chain[CHAIN[y]].size() - 1]];
}
}
if (NR[x] > NR[y]){
cout<<x<<'\n';
}
else{
cout<<y<<'\n';
}
}
return 0;
}