Cod sursa(job #2173259)

Utilizator RickSanchezRick Sanchez RickSanchez Data 15 martie 2018 21:21:48
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.61 kb
#include <bits/stdc++.h>

using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
const int nmax = 1e5 + 5;
int N,M;
int v[2 * nmax], len, poz[nmax], h[nmax], lg[2 * nmax];
int rmq[20][2*nmax];
vector < int > L[nmax];


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

inline void DFS(int nod, int tata)
{
    h[nod] = 1 + h[tata];
    v[++len] = nod; poz[nod] = len;
    for(auto it : L[nod])
    {
        if(it == tata) continue;
        DFS(it,nod);
        v[++len] = nod;
    }
}


inline void BuildRMQ()
{
    int i,j,jmx;
    for(i = 2; i <= len; i++) lg[i] = lg[i >> 1] + 1;
    for(i = 1; i <= len; i++) rmq[0][i] = i;
    jmx = lg[len];
    for(j = 1; j <= jmx; j++)
        for(i = 1; i <= len - (1 << j); i++)
    {
        rmq[j][i]  = rmq[j-1][i];
        if(h[v[rmq[j-1][i + (1 << (j-1))]]] < h[v[rmq[j][i]]])
            rmq[j][i] = rmq[j-1][i + (1 << (j-1))];
    }

}


inline int Query(int x, int y)
{
    int k,nod,j;
    if(x > y ) swap(x,y);
    j = (y - x + 1);
    k = lg[j];
    nod = v[rmq[k][x]];
    if(h[nod] > h[v[rmq[k][y - (1 << k) + 1]]])
        nod = v[rmq[k][y - (1 << k) + 1]];
    return nod;

}

inline void Solve()
{
    int x,y;
    DFS(1,0);
    BuildRMQ();
    while(M--)
    {
        fin >> x >> y;
        x = poz[x]; y = poz[y];
        fout << Query(x,y) << "\n";
    }
}

int main()
{
    Read();
    Solve();
    return 0;
}
///Aveti grija la dimensiunea vectorilor. Bafta la OJI!