Pagini recente » Cod sursa (job #1825832) | Cod sursa (job #1040174) | Cod sursa (job #3004548) | Cod sursa (job #2417141) | Cod sursa (job #2919146)
#include <bits/stdc++.h>
#pragma GCC optimize ("Ofast")
using namespace std;
ifstream fin ("lca.in");
ofstream fout ("lca.out");
const int MAX_N = 100005;
int n, parent, q, x, y, lft, rgt, pw2;
vector <int> leaves[MAX_N];
int m, euler[2 * MAX_N], level[2 * MAX_N], first[MAX_N], lg2[2 * MAX_N], rmq[18][2 * MAX_N];
void dfs_euler(int nod, int lvl){
m++;
euler[m] = nod;
level[m] = lvl;
first[nod] = m;
for(auto leaf : leaves[nod]){
dfs_euler(leaf, lvl+1);
m++;
euler[m] = nod;
level[m] = lvl;
}
}
int main (){
ios_base::sync_with_stdio(false);
fin.tie(nullptr), fout.tie(nullptr);
fin>>n>>q;
for(int i=2; i<=n; i++){
fin>>parent;
leaves[parent].push_back(i);
}
dfs_euler(1, 1);
for(int i=2; i<=m; i++)
lg2[i] = lg2[i>>1] + 1;
for(int j=1; j<=m; j++)
rmq[0][j] = j;
for(int i=1; i<=lg2[m]; i++)
for(int j=1, jj; (jj = j + (1 << (i-1)))<=m; j++)
if(level[ rmq[i-1][j] ] < level[ rmq[i-1][jj] ])
rmq[i][j] = rmq[i-1][j];
else
rmq[i][j] = rmq[i-1][jj];
while(q--){
fin>>x>>y;
lft = min(first[x], first[y]);
rgt = max(first[x], first[y]);
pw2 = lg2[rgt-lft+1];
x = rmq[pw2][lft];
y = rmq[pw2][rgt-(1 << pw2)+1];
if(level[x] < level[y])
fout<<euler[x]<<"\n";
else
fout<<euler[y]<<"\n";
}
return 0;
}