Cod sursa(job #1724987)

Utilizator dani_mocanuDani Mocanu dani_mocanu Data 4 iulie 2016 17:55:09
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.54 kb
#include <bits/stdc++.h>

using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
const int nmax = 200005;
int N,M,v[nmax],len,dp[nmax],poz[nmax],lg[nmax];
int rmq[20][nmax];
vector < int > L[nmax];

inline void Read()
{
    int i,x,y;
    fin >> N >> M;
    for(i = 2; i <= N; i++)
    {
        fin >> x;
        L[x].push_back(i);
    }
    for(i = 2; i <= 2*N; i++) lg[i] = lg[i/2] + 1;
}

inline void DFS(int nod, int level)
{
    int i;
    v[++len] = nod , poz[nod] = len;
    dp[nod] = level;
    for(auto it : L[nod])
    {
        DFS(it,level+1);
        v[++len] = nod;
    }
}

inline void Build_RMQ()
{
    int i,j,Jmx,jpow;
    for(i = 1; i <= len; i++) rmq[0][i] = i;
    Jmx = lg[len];
    for(j = 1; j <= Jmx; j++)
    {
        jpow = (1 << (j - 1));
        for(i = 1; i + 2*jpow <= len; i++)
        {
            rmq[j][i] = rmq[j-1][i];
            if(dp[v[rmq[j][i]]] > dp[v[rmq[j-1][i + jpow]]])
                rmq[j][i] = rmq[j-1][i + jpow];
        }
    }
}

inline int Query(int x, int y)
{
    int l,k,sol,Kpow;
    l = y - x + 1;
    k = lg[l];
    Kpow = (1 << k);
    sol = rmq[k][x];
    if(dp[v[sol]] > dp[v[rmq[k][y + 1 - Kpow]]])
        sol = rmq[k][y - Kpow];
    return v[sol];
}
int main()
{
    int x,y,m1,m2;
    Read();
    DFS(1,0);
    Build_RMQ();
    while(M--)
    {
        fin >> x >> y;
        m1 = min(poz[x],poz[y]);
        m2 = max(poz[x],poz[y]);
        fout << Query(m1, m2) << "\n";
    }
    fout.close();
    return 0;
}