Cod sursa(job #2607376)

Utilizator maramihaliMara Mihali maramihali Data 29 aprilie 2020 17:36:00
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.8 kb
#include <bits/stdc++.h>

using namespace std;

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

const int N = 100001;

int t[N], lst[N], vf[N], urm[N], nr;
int logg2[2 * N], ne, nivel[N], prima[N], e[2 * N], rmq[18][2 * N];

void adauga (int x, int y)
{
    vf[++nr] = y;
    urm[nr] = lst[x];
    lst[x] = nr;
}
void dfs(int nod)
{
    e[++ne] = nod;
    nivel[nod] = 1 + nivel[t[nod]];
    prima[nod] = ne;
    for (int p = lst[nod]; p != 0;p = urm[p])
    {
        int y = vf[p];
        if (prima[y] == 0)
        {
            dfs(y);
            e[++ne] = nod;
        }
    }
}

void loga(int n)
{
    logg2[1] = 0;
    for (int i = 2;i <= 2 * n - 1; i++)
    {
        logg2[i] = logg2[i / 2] + 1;
    }
}
int lca(int x, int y)
{
    int px = prima[x];
    int py =prima[y];
    if(px > py)
    {
        swap(px, py);
    }
    int l = logg2[py - px + 1];
    int st = rmq[l][px + (1 << l) - 1];
    int dr = rmq[l][py];
    if(nivel[e[st]] <= nivel[e[dr]])
    {
        return e[st];
    }
    return e[dr];
}
int main()
{
    int n, m, x, y;
    in >> n >> m;
    for(int i = 2;i <= n; i++)
    {
        in >> x;
        adauga(x, i);
        t[i] = x;
    }
    loga(n);
    dfs(1);
    for(int i = 1;i <= 2 * n - 1; i++)
        rmq[0][i] = i;
    for(int i = 1; (1 << i) <= 2 * n - 1; i++)
    {
        for(int j = 1 << i;j <= 2 * n - 1; j++)
        {
            int st, dr;
            st = rmq[i - 1][j - (1 << (i - 1))];
            dr = rmq[i - 1][j];
            if (nivel[e[st]] > nivel[e[dr]])
            {
                rmq[i][j] = dr;
            }
            else rmq[i][j] = st;
        }
    }
    for(int i = 1; i <= m; i++)
    {
        in >> x >> y;
        out << lca(x, y) << "\n";
    }
    return 0;
}