Cod sursa(job #2434578)

Utilizator bluestorm57Vasile T bluestorm57 Data 2 iulie 2019 12:19:18
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.46 kb
#include <bits/stdc++.h>

using namespace std;

ifstream f("lca.in");
ofstream g("lca.out");

const int NMAX = 100005;
const int LMAX = 20;
vector <int> v[NMAX];
int n,m,k;
int euler[2 * NMAX], lvl[NMAX], pos[NMAX];
int rmq[LMAX][2 * NMAX],lg[2 * NMAX];

void dfs(int nod, int level){
    euler[++k] = nod;
    lvl[nod] = level;
    pos[nod] = k;
    for(auto it: v[nod])
        if(!lvl[it]){
            dfs(it, level + 1);
            euler[++k] = nod;
        }
}

void buildRMQ(){
    int i,j;
    for(i = 1 ; i <= k ; i++)
        rmq[0][i] = euler[i];

    for(i = 2 ; i <= k ; i++)
        lg[i] = lg[i / 2] + 1;

    for(i = 1 ; i <= lg[k] ; i++)
        for(j = 1 ; j <= k - (1 << i) ; j++){
            rmq[i][j] = rmq[i - 1][j];
            if (lvl[rmq[i - 1][j +( 1 << (i - 1) ) ] ] < lvl[rmq[i - 1][j]])
                rmq[i][j] = rmq[i-1][j+(1<<(i-1))];
        }
}

int lca(int x, int y){
    x = pos[x];
    y = pos[y];
    if(x > y)
        swap(x, y);
    int dif = y - x + 1, l = lg[dif];
    if(lvl[rmq[l][x]] < lvl[rmq[l][y - (1 << l) + 1]])
        return rmq[l][x];
    return rmq[l][y - (1 << l) + 1];
}

int main(){
    int i,j,x,y;
    f >> n >> m;
    for(i = 2 ; i <= n ; i++){
        f >> j;
        v[j].push_back(i);
        v[i].push_back(j);
    }

    dfs(1,1);
    buildRMQ();
    for(i = 1 ; i <= m ; i++){
        f >> x >> y;
        g << lca(x,y) << "\n";
    }

    return 0;
}