Cod sursa(job #2196033)

Utilizator Constantin.Dragancea Constantin Constantin. Data 18 aprilie 2018 09:27:48
Problema Lowest Common Ancestor Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 1.18 kb
#include <bits/stdc++.h>
using namespace std;

const int N = 100010;
int n, m, Euler[2*N], lvl[2*N], first[N], k, rmq[20][2*N];
vector <int> v[N];

void dfs(int q, int t){
    lvl[++k] = t;
    Euler[k] = q;
    first[q] = k;
    for (auto it: v[q]){
        dfs(it, t + 1);
        lvl[++k] = t;
        Euler[k] = q;
    }
}

void build(){
    for (int i=1; i<=k; i++) rmq[0][i] = i;
    for (int i=1; (1<<i)<=k; i++){
        for (int j=(1<<i); j<=k; j++)
            if (lvl[rmq[i-1][j]] < lvl[rmq[i-1][j - (1<<(i-1))]]) rmq[i][j] = rmq[i-1][j];
            else rmq[i][j] = rmq[i-1][j-(1<<(i-1))];
    }
}

int query(int st, int dr){
    int put = log2(dr - st + 1);
    if (rmq[put][dr] < rmq[put][st + (1<<put) - 1]) return Euler[rmq[put][dr]];
    else return Euler[rmq[put][st + (1<<put) - 1]];
}

int main(){
    ifstream cin ("lca.in");
    ofstream cout ("lca.out");
    cin >> n >> m;
    for (int i=2, x; i<=n; i++) cin >> x, v[x].push_back(i);
    dfs(1, 1);
    build();
    while (m--){
        int x, y;
        cin >> x >> y;
        if (first[x] > first[y]) swap(x, y);
        cout << query(first[x], first[y]) << "\n";
    }
    return 0;
}