Cod sursa(job #2162221)

Utilizator SolcanMihaiSolcan Mihai Andrei SolcanMihai Data 12 martie 2018 09:13:49
Problema Hashuri Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.68 kb
#include <cstdio>
#include <cmath>
#include <vector>

using namespace std;

int n, m;
vector<int> vecini[100005];
int firstApp[100005];

int nr = 1;
int lca[200005];
int rmq[200005][22];

void citire(){
    scanf("%d %d", &n, &m);
    int x;

    for(int i = 2; i <= n; i++){
        scanf("%d", &x);
        vecini[x].push_back(i);
    }
}

void addInLca(int x, int d){
    rmq[nr][0] = x;
    if(firstApp[x] == 0){
        firstApp[x] = nr;
    }
    if(lca[x] == 0){
        lca[x] = d;
    }
    nr++;
}

void dfs(int x, int d){
    addInLca(x, d);

    int l = vecini[x].size();

    for(int i = 0; i < l; i++){
        dfs(vecini[x][i], d + 1);
        addInLca(x, d);
    }
}

void createRmq(){
    for(int i = 1; (1 << i) <= nr; i++){
        for(int j = 1; j + (1 << (i - 1)) <= nr; j++){
            if(lca[rmq[j][i - 1]] < lca[rmq[j + (1 << (i - 1))][i - 1]]){
                rmq[j][i] = rmq[j][i - 1];
            }
            else{
                rmq[j][i] = rmq[j + (1 << (i - 1))][i - 1];
            }
        }
    }
}

int query(int x, int y){
    x = firstApp[x];
    y = firstApp[y];

    if(x > y){
        swap(x, y);
    }

    int l = y - x + 1;
    int lg = log2(l);

    if(lca[rmq[x][lg]] < lca[rmq[y - (1 << lg) + 1][lg]]){
        return rmq[x][lg];
    }
    else{
        return rmq[y - (1 << lg) + 1][lg];
    }
}

int main()
{
    freopen("lca.in", "r", stdin);
    freopen("lca.out", "w", stdout);

    int x, y;

    citire();
    dfs(1, 1);
    createRmq();

    for(int i = 0; i < m; i++){
        scanf("%d %d", &x, &y);
        printf("%d\n", query(x, y));
    }

    return 0;
}