Cod sursa(job #2455088)

Utilizator StanCatalinStanCatalin StanCatalin Data 10 septembrie 2019 19:14:34
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.61 kb
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

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

const int dim = 100005;

int n,euler[4*dim],lv[dim],cnt,aparitie[dim],rmq[32][4*dim],lg[4*dim],m;
vector <int> vec[dim];

void dfs(int nod,int lev)
{
    euler[++cnt] = nod;
    lv[nod] = lev;
    aparitie[nod] = cnt;

    for (int i=0; i<vec[nod].size(); i++)
    {
        dfs(vec[nod][i] , lev+1);
        euler[++cnt] = nod;
    }
}

int main()
{
    in >> n >> m;
    int x;
    for (int i=2; i<=n; i++)
    {
        in >> x;
        vec[x].push_back(i);
    }
    dfs(1,1);
    for (int i=2; i<=cnt; i++)
    {
        lg[i] = lg[i/2] + 1;
    }
    for (int i=1; i<=cnt; i++)
    {
        rmq[0][i] = euler[i];
    }
    for (int i=1; (1<<i)<=cnt; i++)
    {
        for (int j=1; j+(1<<(i))-1<=cnt; j++)
        {
            if (lv[rmq[i-1][j]] <= lv[rmq[i-1][j+(1<<(i-1))]])
            {
                rmq[i][j] = rmq[i-1][j];
            }
            else
            {
                rmq[i][j] = rmq[i-1][j+(1<<(i-1))];
            }
        }
    }
    int y,logdif;
    for (int i=1; i<=m; i++)
    {
        in >> x >> y;
        x = aparitie[x];
        y = aparitie[y];
        if (x > y)
        {
            swap(x,y);
        }
        logdif = lg[y-x+1];
        if (lv[rmq[logdif][x]] < lv[rmq[logdif][y - (1 << logdif) + 1]])
        {
            out << rmq[logdif][x] << "\n";
        }
        else
        {
            out << rmq[logdif][y - (1 << logdif) + 1] << "\n";
        }
    }
    return 0;
}