Cod sursa(job #2952128)

Utilizator ioana.cCaprariu Ioana ioana.c Data 8 decembrie 2022 15:23:35
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.3 kb
#include <fstream>
#include <vector>

using namespace std;

ifstream fin("lca.in");
ofstream fout("lca.out");

const int NMAX=1e5+5;

int te[NMAX];
int lvl[NMAX];

int t[20][NMAX];
int rmq[20][NMAX];

int n, q, x, y, c;

vector <int> v[NMAX];

void dfs(int p, int tata){
    lvl[p] = lvl[tata] + 1;
    rmq[0][p] = tata;
    for(auto i:v[p])
        if(i != tata){
            t[0][i] = i;
            dfs(i,p);
        }
}

void RMQ(){
    for(int e=1; (1<<e)<=n; e++)
        for(int i=1; i<=n; i++){
            rmq[e][i] = rmq[e-1][rmq[e-1][i]];
            t[e][i] = max(t[e-1][i], t[e-1][rmq[e-1][i]]);
        }
}

int lca(int x, int y){
    int level;
    if(lvl[x] < lvl[y])
        swap(x,y);
    level = lvl[x] - lvl[y];
    for(int e=15; e>=0; e--)
        if(level & (1<<e))
            x = rmq[e][x];
    if(x == y)
        return x;
    for(int e=15; e>=0; e--)
        if(rmq[e][x] != rmq[e][y]){
            x = rmq[e][x];
            y = rmq[e][y];
        }
    return rmq[0][x];
}

int main(){
    fin >> n >> q;
    for(int i=2; i<=n; i++){
        fin >> x;
        v[x].push_back(i);
        v[i].push_back(x);
    }
    dfs(1,0);
    RMQ();
    while(q--){
        fin >> x >> y;
        fout << lca(x,y) << '\n';
    }
    return 0;
}