Cod sursa(job #1922361)

Utilizator dorin31Geman Dorin Andrei dorin31 Data 10 martie 2017 17:08:45
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.5 kb
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

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

#define maxN 100010
#define maxLog 20

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

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

void DFS(int nod, int lv)
{
    euler[++nr_rmq]=nod;
    lvl[nr_rmq]=lv;
    first[nod]=nr_rmq;
    for (auto it:v[nod])
    {
        DFS(it,lv+1);
        euler[++nr_rmq]=nod;
        lvl[nr_rmq]=lv;
    }
}

inline int minimByLevel(int lvl[], int a, int b)
{
    if (lvl[a]<lvl[b]) return a;
    return b;
}

void buildRMQ()
{
    lg[1]=0;
    for (int i=2; i<=nr_rmq; ++i)
        lg[i]=lg[i/2]+1;

    for (int i=1; i<=nr_rmq; ++i)
        rmq[0][i]=i;

    for (int i=1; (1<<i)<=nr_rmq; ++i)
        for (int j=1; j<=nr_rmq-(1<<i)+1; ++j)
        {
            rmq[i][j]=minimByLevel(lvl,rmq[i-1][j],rmq[i-1][j+(1<<(i-1))]);
        }
}

int LCA(int x, int y)
{
    int a=first[x], b=first[y];
    if (a>b) swap(a,b);
    int diff,line,s;
    diff=b-a+1;
    line=lg[diff];
    s=diff-(1<<line);
    return euler[minimByLevel(lvl,rmq[line][a],rmq[line][a+s])];
}

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