Cod sursa(job #2406630)

Utilizator radumihaisirbuSirbu Radu-Mihai radumihaisirbu Data 15 aprilie 2019 22:49:08
Problema Lowest Common Ancestor Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.75 kb
#include <bits/stdc++.h>

using namespace std;

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

const int nmax = 1e5 + 5, inf = 1e9;

int z = 1;

vector <int> v[nmax], First(nmax), H(nmax << 1), arbint(nmax << 4), L(nmax << 1);

int n, q, k, x, y, sol_h, sol_node, start, finish;

void build(int ls = 1, int ld = k, int pos = 1)
{
    if (ls == ld)
    {
        arbint[pos] = ls;
        return;
    }

    int mij = (ls + ld) / 2;

    build(ls, mij, 2*pos);
    build(mij+1, ld, 2*pos+1);

    if (L[arbint[2*pos]] < L[arbint[2*pos+1]])
    {
        arbint[pos] = arbint[2*pos];
    }
    else
    {
        arbint[pos] = arbint[2*pos+1];
    }
}

void query(int ls = 1, int ld = k, int pos = 1)
{
    int mij;

    if (ls >= start && ld <= finish)
    {
        if (L[arbint[pos]] < sol_h)
        {
            sol_node = H[arbint[pos]];
            sol_h = L[arbint[pos]];
        }
        return;
    }

    mij = (ls + ld) / 2;
    if (start <= mij) query(ls, mij, 2*pos);
    if (mij < finish) query(mij+1, ld, 2*pos+1);
}

int lca()
{
    start = First[x];
    finish = First[y];
    if (start > finish) swap(start, finish);
    sol_h = inf;

    query();

    return sol_node;
}

void dfs (int nod = 1, int niv = 0)
{
    H[++k] = nod;
    L[k] = niv;
    First[nod] = k;

    for (vector <int> :: iterator it=v[nod].begin(); it!=v[nod].end(); ++it)
    {
        dfs(*it, niv+1);
        H[++k] = nod;
        L[k] = niv;
    }
}

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