Cod sursa(job #2347837)

Utilizator Mihai145Oprea Mihai Adrian Mihai145 Data 19 februarie 2019 10:10:40
Problema Lowest Common Ancestor Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.52 kb
#include <fstream>

using namespace std;

ifstream fin("lca.in");
ofstream fout("lca.out");

const int LOGN = 18;
const int NMAX = 100000 + 5;

int N, Q;
int nivel[NMAX], str[LOGN][NMAX];

void InitStramosi()
{
    for(int j = 1; j <= LOGN - 2; j++)
        {
            if(j == 10)
                j++, j--;

            for(int i = 1; i <= N; i++)
                str[j][i] = str[j - 1][str[j - 1][i]];
        }
}

void SetLevel(int nod)
{
    if(nivel[nod] == 0)
    {
        SetLevel(str[0][nod]);
        nivel[nod] = nivel[str[0][nod]] + 1;
    }
}

void InitNivel()
{
    nivel[1] = 1;

    for(int i = 2; i <= N; i++)
        if(nivel[i] == 0)
            SetLevel(i);
}

int Bring(int x, int target)
{
    for(int i = LOGN - 2; i >= 0; i--)
        if(nivel[str[i][x]] >= target)
            x = str[i][x];

    return x;
}

int LCA(int x, int y)
{
    if(nivel[x] > nivel[y])
        x = Bring(x, nivel[y]);
    else if(nivel[x] < nivel[y])
        y = Bring(y, nivel[x]);

    for(int i = LOGN - 2; i >= 0; i--)
        if(str[i][x] != str[i][y])
        {
            x = str[i][x];
            y = str[i][y];
        }

    if(x != y)
        x = str[0][x];

    return x;
}

int main()
{
    fin >> N >> Q;

    for(int i = 1; i <= N - 1; i++)
        fin >> str[0][i + 1];

    InitStramosi();
    InitNivel();

    int x, y;
    for(int i = 1; i <= Q; i++)
    {
        fin >> x >> y;
        fout << LCA(x, y) << '\n';
    }

    return 0;
}