Cod sursa(job #2870350)

Utilizator alex_braslasuBraslasu Alexandru alex_braslasu Data 12 martie 2022 11:53:34
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.58 kb
#include <fstream>
#include <vector>

#define N_MAX 100010

using namespace std;

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

int n, m, cnt, i, j, x, y, x1, y1, tata[N_MAX], first_ap[N_MAX], niv[N_MAX], e[3 * N_MAX], rmq[3 * N_MAX][20], lg[3 * N_MAX];
vector<int > fiu[N_MAX];

static inline void Euler(int nod, int nivel)
{
    niv[nod] = nivel;
    first_ap[nod] = cnt + 1;
    for (auto it : fiu[nod])
    {
        e[++cnt] = nod;
        Euler(it, nivel + 1);
    }
    e[++cnt] = nod;
}

static inline int LCA(int x, int y)
{
    int z = y - x + 1;
    z = lg[z];
    int xx = rmq[x][z];
    int yy = rmq[y - (1 << z) + 1][z];
    if (niv[xx] < niv[yy])
        return xx;
    return yy;
}

int main()
{
    f >> n >> m;
    for (i = 1; i < n; ++i)
    {
        f >> tata[i + 1];
        fiu[tata[i + 1]].push_back(i + 1);
    }
    Euler(1, 1);
    for (i = 1; i <= cnt; ++i)
        rmq[i][0] = e[i];
    for (j = 1; (1 << j) <= cnt; ++j)
    {
        for (i = 1; i + (1 << j) <= cnt; ++i)
        {
            int xx = niv[rmq[i][j - 1]];
            int yy = niv[rmq[i + (1 << (j - 1))][j - 1]];
            if (xx < yy)
                rmq[i][j] = rmq[i][j - 1];
            else
                rmq[i][j] = rmq[i + (1 << (j - 1))][j - 1];
        }
    }
    for (i = 2; i <= cnt; ++i)
        lg[i] = lg[i >> 1] + 1;
    for (i = 1; i <= m; ++i)
    {
        f >> x >> y;
        x = first_ap[x];
        y = first_ap[y];
        x1 = min(x, y);
        y1 = max(x, y);
        g << LCA(x1, y1) << '\n';
    }
    return 0;
}