Cod sursa(job #2376748)

Utilizator AlexrotaruRotaru Alexandru Alexrotaru Data 8 martie 2019 17:24:52
Problema Lowest Common Ancestor Scor 30
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.86 kb
#include <fstream>
using namespace std;

int t[100100], n, m,
    v[300100], h[300100], le,
    arb[300100];

void reprezEuler(int r = 1, int hc = 1)
{
    for(int i = 1; i <= n; i++)
        if(t[i] == r)
        {
            v[le] = r;
            h[le++] = hc;
            reprezEuler(i, hc + 1);
        }
    v[le] = r;
    h[le++] = hc;
}

void update(int poz, int st, int dr, int k = 1)
{
    if(st == dr)
    {
        arb[k] = poz;
        return;
    }

    if(poz <= (st + dr) / 2)
        update(poz, st, (st + dr) / 2, k * 2);
    else
        update(poz, (st + dr) / 2 + 1, dr, k * 2 + 1);
    if(h[arb[k * 2]] <= h[arb[k * 2 + 1]])
        arb[k] = arb[k * 2];
    else
        arb[k] = arb[k * 2 + 1];
}

int query(int a, int b, int st, int dr, int k = 1)
{
    int rez = -1, q;

    if(a <= st && b >= dr)
        return arb[k];

    if(a <= (st + dr) / 2)
    {
        q = query(a, b, st, (st + dr) / 2, k * 2);
        if(rez == -1 || (h[q] < h[rez]))
            rez = q;
    }
    if(b > (st + dr) / 2)
    {
        q = query(a, b, (st + dr) / 2 + 1, dr, k * 2 + 1);
        if(rez == -1 || (h[q] < h[rez]))
            rez = q;
    }

    return rez;
}

void constrArbInterv()
{
    for(int i = 0; i < le; i++)
        update(i, 0, le - 1);
}

int lca(int a, int b)
{
    int i = -1, j = -1, k = 0;
    while((i == -1 || j == -1) && k < le)
    {
        if(i == -1 && v[k] == a)
            i = k;
        if(j == -1 && v[k] == b)
            j = k;
        k++;
    }
    if(i > j)
        swap(i, j);
    return v[query(i, j, 0, le - 1)];
}

int main()
{

    ifstream in("lca.in");
    ofstream out("lca.out");
    int x, y;

    in >> n >> m;
    for(int i = 2; i <= n; i++)
        in >> t[i];
    reprezEuler();
    constrArbInterv();
    for(int i = 0; i < m; i++)
    {
        in >> x >> y;
        out << lca(x, y) << endl;
    }
    in.close();
    out.close();
}