Pagini recente » Cod sursa (job #2129939) | Cod sursa (job #2140333) | Cod sursa (job #1589666) | Cod sursa (job #1250811) | Cod sursa (job #3177224)
//solutie cu rmq
#include <fstream>
#include <vector>
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");
const int nmax = 100005;
vector<int> l[nmax];
struct rmq{
int node, lvl;
}dp[19][2 * nmax];
int euler[2 * nmax], cnt, poz[2 * nmax], Log2[2 * nmax];
int n, m;
void dfs(int nod, int niv){
dp[0][++cnt] = {nod, niv};
poz[nod] = cnt;
for(auto vec: l[nod]){
dfs(vec, niv + 1);
dp[0][++cnt] = {nod, niv};
}
}
void rangeminquery(){
for(int p = 1; p < 19; p++){
for(int i = 1; i <= cnt; i++){
rmq st = dp[p - 1][i];
if(i + (1 << (p - 1)) <= cnt){
rmq dr = dp[p - 1][i + (1 << (p - 1))];
if(st.lvl < dr.lvl){
dp[p][i] = st;
}
else{
dp[p][i] = dr;
}
}
else{
dp[p][i] = st;
}
}
}
}
int lca(int a, int b){
int poz_a = poz[a];
int poz_b = poz[b];
if(poz_a > poz_b){
swap(poz_a, poz_b);
}
int p = Log2[poz_b - poz_a + 1];
rmq st = dp[p][poz_a];
rmq dr = dp[p][poz_b - (1 << p) + 1];
if(st.lvl < dr.lvl){
return st.node;
}
else{
return dr.node;
}
}
int main(){
f >> n >> m;
for(int i = 2; i <= n; i++){
int x;
f >> x;
l[x].push_back(i);
}
cnt = 0;
dfs(1, 1);
rangeminquery();
Log2[1] = 0;
for(int i = 2; i <= cnt; i++){
Log2[i] = Log2[i / 2] + 1;
}
while(m--){
int x, y;
f >> x >> y;
g << lca(x, y) << '\n';
}
return 0;
}