Pagini recente » Cod sursa (job #845997) | Cod sursa (job #1549694) | Cod sursa (job #1170283) | Cod sursa (job #2097292) | Cod sursa (job #2100003)
#include <fstream>
#include <vector>
using namespace std;
ifstream cin ("lca.in");
ofstream cout ("lca.out");
int dp[20][100100];
int LOG[100100];
vector < vector < int > > gr(100100);
vector < int > dad (100100);
vector < int > G (100100);
vector < int > lv (100100);
int cont = 0;
vector < vector < int > > chain(100100);
vector < int > CHAIN(100100);
vector < int > NR(100100);
vector < int > LV(100100);
vector < vector < int > > GR(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 (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;
}
else{
chain[CHAIN[go]].push_back(root);
CHAIN[root] = CHAIN[go];
NR[root] = chain[CHAIN[root]].size() - 1;
for (auto &x : gr[root]){
if (x == go){
continue;
}
GR[CHAIN[root]].push_back(CHAIN[x]);
}
}
}
void DFS(int root){
for (auto &x : GR[root]){
LV[x] = LV[root] + 1;
dp[0][x] = root;
DFS(x);
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
//stramosi pe hpd
int n , m;
cin>>n>>m;
for (int i=2; i<=n; i++){
LOG[i] = LOG[i/2] + 1;
}
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';*/
DFS(CHAIN[1]);
for (int bit=1; bit <= LOG[n]; bit++){
for (int i=1; i<=n; i++){
dp[bit][i] = dp[bit-1][dp[bit-1][i]];
}
}
for (int i=1; i<=m; i++){
int x , y;
cin>>x>>y;
int cx = CHAIN[x];
int cy = CHAIN[y];
int pos;
//cout<<LV[cx]<<" "<<LV[cy]<<'\n';
if (LV[cx] > LV[cy]){
pos = LV[cx] - LV[cy] - 1;
while (pos){
cx = dp[LOG[pos]][cx];
pos -= (1 << LOG[pos]);
}
x = dad[chain[cx][chain[cx].size()-1]];
cx = dp[0][cx];
}
if (LV[cy] > LV[cx]){
pos = LV[cy] - LV[cx] - 1;
while (pos){
cy = dp[LOG[pos]][cy];
pos -= (1 << LOG[pos]);
}
y = dad[chain[cy][chain[cy].size()-1]];
cy = dp[0][cy];
}
if (cx == cy){
if (NR[x] > NR[y]){
cout<<x<<'\n';
}
else{
cout<<y<<'\n';
}
continue;
}
for (int bit = LOG[LV[cx]]; bit >=0; bit--){
if (dp[bit][cx] != dp[bit][cy]){
cx = dp[bit][cx];
cy = dp[bit][cy];
}
}
x = dad[chain[cx][chain[cx].size()-1]];
y = dad[chain[cy][chain[cy].size()-1]];
if (NR[x] > NR[y]){
cout<<x<<'\n';
}
else{
cout<<y<<'\n';
}
}
return 0;
}