Cod sursa(job #2972877)

Utilizator IoanMihaiIoan Mihai IoanMihai Data 30 ianuarie 2023 16:13:41
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.39 kb
#include <bits/stdc++.h>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
const int NMAX = 100005;
const int EMAX = NMAX * 3;
const int LMAX = 18;
int n, m, x, y, nr;
int h[EMAX], eul[EMAX], first[NMAX], rmq[LMAX][EMAX], lg[EMAX];
vector<int> G[NMAX];

void dfs(int nod, int lev)
{
    ++nr;
    eul[nr] = nod;
    h[nr] = lev;
    first[nod] = nr;
    for (auto it : G[nod]){
        dfs(it, lev+1);
        eul[++nr] = nod;
        h[nr] = lev;
    }
}

void build_rmq()
{
    for (int i=2;i<=nr;i++)
        lg[i] = lg[(i>>1)] + 1;
    for (int i=1;i<=nr;i++){
        rmq[0][i] = i;
    }
    for (int i=1;(1 << i)<=nr;i++){
        for (int j=1;j<=nr - (1<<i);j++){
            int lg2 = 1 << (i - 1);
            if (h[rmq[i-1][j]] < h[rmq[i-1][j+lg2]])
                rmq[i][j] = rmq[i-1][j];
            else
                rmq[i][j] = rmq[i-1][j+lg2];
        }
    }
}

int lca(int x, int y)
{
    x = first[x];
    y = first[y];
    if (x > y)
        swap(x, y);
    int lg2 = lg[y - x + 1], poz;
    if (h[rmq[lg2][x]] < h[rmq[lg2][y - (1 << lg2) + 1]])
        poz = rmq[lg2][x];
    else    
        poz = rmq[lg2][y - (1 << lg2) + 1];
    return eul[poz];
}

int main()
{
    fin >> n >> m;
    for (int i=2;i<=n;i++){
        fin >> x;
        G[x].push_back(i);
    }

    dfs(1, 1);
    build_rmq();
    while(m --){
        fin >> x >> y;
        fout << lca(x, y) << '\n';
    }
}