Cod sursa(job #1921644)

Utilizator dorin31Geman Dorin Andrei dorin31 Data 10 martie 2017 13:38:34
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.39 kb
#include <iostream>
#include <fstream>
#include <vector>

#define maxN 100010

using namespace std;

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

int n,m,nr_rmq,rmq[20][2*maxN],first[2*maxN],lvl[maxN];
vector <int> v[maxN];

void readData()
{
    fin>>n>>m;
    for (int i=2; i<=n; ++i)
    {
        int x;
        fin>>x;
        v[x].push_back(i);
    }
}

void DFS(int x)
{
    rmq[0][++nr_rmq]=x;
    first[x]=nr_rmq;
    for (auto it:v[x])
    {
        lvl[it]=lvl[x]+1;
        DFS(it);
        rmq[0][++nr_rmq]=x;
    }
}

void makeRMQ()
{
    for (int l = 1; (1 << l) <= nr_rmq; ++l)
        for (int st = 1; st + (1 << l) <= nr_rmq; ++st) {
            int dr = st + (1 << (l - 1));
            if (lvl[rmq[l - 1][st]] < lvl[rmq[l - 1][dr]])
                rmq[l][st] = rmq[l - 1][st];
            else
                rmq[l][st] = rmq[l - 1][dr];
        }
}

int LCA(int a, int b)
{
    a=first[a];
    b=first[b];
    if (a>b) swap(a,b);
    else if (a==b) return a;
    int d = 0;
    while ((1 << d) < (b - a + 1))
        ++d;
    --d;
    if (lvl[rmq[d][a]] < lvl[rmq[d][b - (1 << d) + 1]])
        return rmq[d][a];
    return rmq[d][b - (1 << d) + 1];
}

int main()
{
    readData();
    DFS(1);
    makeRMQ();
    while (m--)
    {
        int x,y;
        fin>>x>>y;
        fout<<LCA(x,y)<<'\n';
    }
    return 0;
}