Cod sursa(job #2728253)

Utilizator Razvan48Capatina Razvan Nicolae Razvan48 Data 22 martie 2021 22:48:07
Problema Lowest Common Ancestor Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.03 kb
#include <fstream>
#include <vector>

using namespace std;

/// complexitate 1 per query cu RMQ (solutie finala)

const int NMAX = 100000;
const int LOG = 18;

vector<int> graf[1 + NMAX];

int rmq[1 + 2 * NMAX - 1][LOG]; /// 2 * NMAX - 1 celule e suficient

vector<int> liniarizare;

int adancime[1 + NMAX];
int primaAparitie[1 + NMAX];

int putere2Max[1 + 2 * NMAX - 1]; /// 2 * NMAX - 1 celule e suficient

int n;

void dfs(int nod, int adanc)
{
    liniarizare.emplace_back(nod);
    primaAparitie[nod] = liniarizare.size() - 1;

    adancime[nod] = adanc;

    for (int i = 0; i < graf[nod].size(); i++)
    {
        dfs(graf[nod][i], 1 + adanc);

        liniarizare.emplace_back(nod);
    }
}

void RMQ()
{
    for (int i = 1; i <= 2 * n - 1; i++)
    {
        rmq[i][0] = adancime[liniarizare[i]];
    }

    for (int l = 1; (1 << l) <= 2 * n - 1; l++)
    {
        for (int i = 1; i <= 2 * n - 1 - (1 << l) + 1; i++)
        {
            rmq[i][l] = min(rmq[i][l - 1], rmq[i + (1 << (l - 1))][l - 1]);
        }
    }

    int putere2 = 1;
    int exp = 0;

    for (int i = 1; i <= 2 * n - 1; i++)
    {
        if (putere2 * 2 <= i)
        {
            putere2 *= 2;
            exp++;
        }

        putere2Max[i] = exp;
    }
}

int main()
{
    ifstream in("lca.in");
    ofstream out("lca.out");

    int m;

    in >> n >> m;

    for (int i = 2; i <= n; i++)
    {
        int x;

        in >> x;

        graf[x].emplace_back(i);
    }

    liniarizare.emplace_back(0);

    dfs(1, 1);

    RMQ();



    for (int j = 1; j <= m; j++)
    {
        int x, y;

        in >> x >> y;

        if (primaAparitie[x] > primaAparitie[y])
        {
            swap(x, y);
        }

        out << min(rmq[primaAparitie[x]][putere2Max[primaAparitie[y] - primaAparitie[x] + 1]], rmq[primaAparitie[y] - (1 << putere2Max[primaAparitie[y] - primaAparitie[x] + 1]) + 1][putere2Max[primaAparitie[y] - primaAparitie[x] + 1]]) << '\n';
    }

    return 0;
}