Cod sursa(job #2361408)

Utilizator Anastasia11Susciuc Anastasia Anastasia11 Data 2 martie 2019 15:21:09
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.33 kb
#include <iostream>
#include <fstream>
#include <vector>
#define Nmax 100005

using namespace std;

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

int n, q, x;
vector <int> v[Nmax];
int log2[2*Nmax], first[2*Nmax], eul[2*Nmax];
int ne, niv[Nmax];
int rmq[19][2*Nmax];

void dfs(int x)
{
    eul[++ne]=x;
    first[x]=ne;
    for (auto y:v[x])
    {
        niv[y]=niv[x]+1;
        dfs(y);
        eul[++ne]=x;
    }
}

void RMQ()
{
    for (int i = 2; i <= ne; i++)
        log2[i]=log2[i/2]+1;
    for (int i = 1; i <= ne; i++)
        rmq[0][i]=eul[i];

    for (int i = 1; (1<<i) <= ne; i++)
        for (int j = 0; j+(1<<i)-1 <= ne; j++)
        {
            int x=rmq[i-1][j];
            int y=rmq[i-1][j+(1<<(i-1))];
            if(niv[x]<niv[y]) rmq[i][j]=x;
            else rmq[i][j]=y;
        }
}

int query(int x, int y)
{
    int a=first[x];
    int b=first[y];
    if(a > b) swap(b, a);
    int i=log2[b-a+1];
    int aa=rmq[i][a];
    int bb=rmq[i][b-(1<<i)+1];
    if(niv[aa]<niv[bb]) return aa;
    else return bb;
}

int main()
{
    f >> n >> q;
    for (int i = 2; i <= n; i++)
    {
        f >> x;
        v[x].push_back(i);
    }
    dfs(1);
    RMQ();
    int x, y;
    while(q--)
    {
        f >> x >> y;
        g << query(x, y) << '\n';
    }

    return 0;
}