Cod sursa(job #2401514)

Utilizator Teo_1101Mititelu Teodor Teo_1101 Data 9 aprilie 2019 19:33:22
Problema Lowest Common Ancestor Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.53 kb
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

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

const int NMAX = 250001;

int N, Q;
int log[NMAX];
int Lev[NMAX];
int T[19][NMAX];

vector < int > Ad[NMAX];

void LCA(int x, int y)
{
    if(Lev[x] < Lev[y])
        swap(x, y);

    //fout << x << ' ' << y << ' ' << Lev[x] << ' ' << Lev[y] << ' ' << log[Lev[x]] << ' ' << log[Lev[y]] << ' ';
    for(int k = log[Lev[x]]; k >= 0; --k)
        if(Lev[x] - (1 << k) >= Lev[y]) x = T[k][x];

    if( x == y ) {fout << x << '\n'; return ;}

    for(int k = log[Lev[y]]; k >= 0; --k)
        if( T[k][x] && T[k][x] != T[k][y] )
    {
        x = T[k][y];
        y = T[k][x];
    }

    fout << T[0][x] << '\n';
}

void DFS(int nod, int lev)
{
    Lev[nod] = lev;

    for(int i = 0; i < Ad[nod].size(); ++i)
    {
        int w = Ad[nod][i];

        if( !Lev[w] ) DFS(w, lev + 1);
    }
}

void Do()
{

    fin >> N >> Q;

    log[2] = 1;
    for(int i = 3; i <= N; ++i)
        log[i] = log[i/2] + 1;

    for(int i = 2; i <= N; ++i)
        {
            fin >> T[0][i];

            Ad[ T[0][i] ].push_back( i );
        }

    for(int k = 1; (1 << k) <= N; ++k)
        for(int i = 1; i <= N; ++i)
        T[k][i] = T[k-1][T[k-1][i]];

    for(int i = 1; i <= N; ++i)
        if( !Lev[i] ) DFS(i, 0);

    int x, y;

    for(int q = 1; q <= Q; ++q)
    {
        fin >> x >> y;
        LCA(x, y);
    }
}
int main()
{
    Do();
    return 0;
}