Cod sursa(job #2727900)

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

using namespace std;

const int NMAX = 100000;
const int LOG = 17;

vector<int> graf[1 + NMAX];

int tata[1 + NMAX][LOG];
int adancime[1 + NMAX];

void dfs(int nod, int adanc)
{
    adancime[nod] = adanc;

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

int nodX;
int nodY;

inline bool ok(int adanc)
{
    int exp = 0;

    while (adanc > 0)
    {
        if (adanc % 2 == 1)
        {
            nodX = tata[nodX][exp];
            nodY = tata[nodY][exp];
        }

        adanc /= 2;
        exp++;
    }

    return nodX == nodY;
}

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

    int n, m;

    in >> n >> m;

    for (int i = 2; i <= n; i++)
    {
        in >> tata[i][0];

        graf[tata[i][0]].emplace_back(i);
    }

    for (int i = 2; i <= n; i++)
    {
        int nod = tata[i][0];

        for (int j = 1; j < LOG; j++)
        {
            nod = tata[nod][j - 1];
            tata[i][j] = nod;
        }
    }

    dfs(1, 1);

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

        in >> x >> y;

        if (adancime[x] < adancime[y])
        {
            swap(x, y);
        }

        int difAdancime = adancime[x] - adancime[y];
        int exp = 0;

        while (difAdancime > 0)
        {
            if (difAdancime % 2 == 1)
            {
                x = tata[x][exp];
            }

            difAdancime /= 2;
            exp++;
        }

        if (x == y)
        {
            out << x << '\n';
        }
        else
        {

            int st = 1;
            int dr = adancime[x] - 1;

            int nodSol = 0;

            while (st <= dr)
            {
                int mij = (st + dr) / 2;

                nodX = x;
                nodY = y;

                if (ok(mij))
                {
                    nodSol = nodX;

                    dr = mij - 1;
                }
                else
                {
                    st = mij + 1;
                }
            }

            out << nodSol << '\n';

        }
    }

    return 0;
}