Cod sursa(job #2125886)

Utilizator Constantin.Dragancea Constantin Constantin. Data 8 februarie 2018 20:28:45
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.28 kb
#include <bits/stdc++.h>
using namespace std;

int n, m, x, y, Euler[200010], e, Lvl[200010], First[100010], RMQ[200010][20];
vector <int> V[100005];

int rmq(int st, int dr){
    int l = dr - st + 1, k=0;
    while ((1<<(k+1)) <= l) k++;
    if (Lvl[RMQ[st][k]] < Lvl[RMQ[st + l - (1<<k)][k]]) return Euler[RMQ[st][k]];
    else return Euler[RMQ[st + l - (1<<k)][k]];
}

void dfs(int q, int lvl){
    Euler[++e] = q;
    Lvl[e] = lvl;
    First[q] = e;
    for (auto it: V[q]){
        dfs(it, lvl + 1);
        Euler[++e] = q;
        Lvl[e] = lvl;
    }
}

int main(){
    ios_base::sync_with_stdio(0); cin.tie(0);
    ifstream cin ("lca.in");
    ofstream cout ("lca.out");
    cin >> n >> m;
    for (int i=2; i<=n; i++){
        cin >> x;
        V[x].push_back(i);
    }
    dfs(1,1);
    //preprocessing pt rmq
    for (int i=1; i<=e; i++) RMQ[i][0] = i;
    for (int j=1; (1<<j) < e; j++){
        for (int i=1; i + (1<<j) <= e; i++){
            if (Lvl[RMQ[i][j-1]] < Lvl[RMQ[i + (1<<(j-1))][j-1]]) RMQ[i][j] = RMQ[i][j-1];
            else RMQ[i][j] = RMQ[i + (1<<(j-1))][j-1];
        }
    }
    while (m--){
        cin >> x >> y;
        if (First[y] < First[x]) swap(x,y);
        cout << rmq(First[x],First[y]) << "\n";
    }
    return 0;
}