Cod sursa(job #2367788)

Utilizator DavidLDavid Lauran DavidL Data 5 martie 2019 12:15:31
Problema Lowest Common Ancestor Scor 20
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.84 kb
#include <bits/stdc++.h>
using namespace std;
ifstream fi("lca.in");
ofstream fo("lca.out");

const int NMAX = 1e5 + 5;
const int LOG = 25;

struct multe
{
    int val, poz;
};

vector <int> G[NMAX];
int p[NMAX], niv[NMAX];
int n, m;
vector <int> repr;
multe rmq[LOG][2 * NMAX];
int pr[NMAX];
int lg[NMAX];

void calcLg()
{
    lg[1] = 0;

    for (int i = 2; i <= n; i++)
        if ((1 << (lg[i - 1] + 1)) <= i)
            lg[i] = lg[i - 1] + 1;
        else
            lg[i] = lg[i - 1];
}

void dfs(int nod)
{
    repr.push_back(nod);
    pr[nod] = repr.size() - 1;
    for (auto v: G[nod])
    {
        niv[v] = niv[nod] + 1;
        dfs(v);
        repr.push_back(nod);
    }
}

void getRmq()
{
    int l = repr.size();
    for (int j = 0; j < l; j++)
        rmq[0][j] = {niv[repr[j]], repr[j]};

    for (int i = 1; (1 << i) <= l; i++)
    {
        for (int j = 0; j < l; j++)
            if (j + (1 << i) - 1 < l) /// intra
            {
                if (rmq[i - 1][j].val < rmq[i - 1][j + (1 << (i - 1))].val)
                    rmq[i][j] = rmq[i - 1][j];
                else
                    rmq[i][j] = rmq[i - 1][j + (1 << (i - 1))];
            }
    }
}

int getMin(int a, int b)
{
    int d = lg[b - a + 1];
    if (rmq[d][a].val < rmq[d][b - (1 << d) + 1].val)
        return rmq[d][a].poz;
    return rmq[d][b - (1 << d) + 1].poz;
}

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

    dfs(1);

    calcLg();

    getRmq();

    while (m--)
    {
        int u, v;
        fi >> u >> v;
        if (pr[u] > pr[v])
            swap(u, v);
        if (u == v)
            fo << u << "\n";
        else
            fo << getMin(pr[u], pr[v]) << "\n";
    }

    return 0;
}