Cod sursa(job #2977272)

Utilizator iProgramInCppiProgramInCpp iProgramInCpp Data 11 februarie 2023 10:36:40
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.41 kb
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
ifstream fin ("stramosi.in");
ofstream fout("stramosi.out");
#define NMAX 250001
#define LMAX 20

/**
T[i][j] : Al 2^j -lea stramos al nodului i.
*/
int T[NMAX][LMAX];
vector<int> F[NMAX];
int tin[NMAX], tout[NMAX];
int n,m;
int timp=0;

void dfs(int x)
{
    tin[x] = ++timp;

    for (const int &i: F[x])
    {
        dfs(i);
    }

    tout[x] = ++timp;
}

bool isancestor(int x, int y)
{
    if (x == 0) return true;
    return tin[x] < tin[y] && tout[x] > tout[y];
}

int LCA(int x, int y)
{
    if (isancestor(x,y)) return x;
    if (isancestor(y,x)) return y;

    for (int j=LMAX; j>=0; j--)
    {
        if (!isancestor(T[x][j],y))
            x=T[x][j];
    }

    return T[x][0];
}

int main()
{
    fin >> n >> m;
    for (int i=2; i<=n; i++)
    {
        fin >> T[i][0];
        F[T[i][0]].push_back(i);
    }

    for (int i=1; i<=n; i++)
    {
        if (T[i][0] == 0)
            dfs(i);
    }

    for (int j=1; j<LMAX; j++)
    {
        for (int i=1; i<=n; i++)
        {
            /// Al 2^j-lea stramos al nostru este al 2^(j-1)-lea stramos al stramosului 2^(j-1).
            T[i][j] = T[ T[i][j-1] ][j-1];
        }
    }
    for (int i=0; i<m; i++)
    {
        int a,b;
        fin >> a >> b;
        fout << LCA(a,b) << '\n';
    }

    return 0;
}