Cod sursa(job #1884213)

Utilizator topala.andreiTopala Andrei topala.andrei Data 18 februarie 2017 15:35:35
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.51 kb
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");
const int maxn= 100005;
const int maxl=20;
int N,M,K;
int L[maxn << 1], H[maxn << 1],Lg[maxn << 1], First[maxn];
int Rmq[maxl][maxn << 2];
vector <int>G[maxn];
void citire()
{
    int i,x;
    f>>N>>M;
    for (i=2;i<=N;i++)
    {
        f>>x;
        G[x].push_back(i);
    }
}
void dfs(int nod, int lev)
{
    H[++K] = nod;
    L[K] = lev;
    First[nod] = K;
    int sz=G[nod].size(),i;

    for (i=0;i<sz;i++)
    {

        dfs(G[nod][i], lev+1);
        H[++K] = nod;
        L[K] = lev;
    }
}
void rmq()
{
    for(int i = 2; i <= K; ++i)
        Lg[i] = Lg[i >> 1] + 1;

    for(int i = 1; i <= K; ++i)
        Rmq[0][i] = i;

    for(int i = 1; (1 << i) < K; ++i)
        for(int j = 1; j <= K - (1 << i); ++j)
        {
            int k = 1 << (i - 1);
            Rmq[i][j] = Rmq[i-1][j];
            if(L[ Rmq[i][j] ] > L[ Rmq[i - 1][j + k] ])
                Rmq[i][j] = Rmq[i-1][j + k];
        }
}
void lca(int x, int y)
{
    int diff, k, sol, sh;
    int a = First[x], b = First[y];
    if(a>b) swap(a,b);

    diff = b - a + 1;
    k=Lg[diff];
    sol = Rmq[k][a];
    sh = diff - (1<<k);

    if(L[sol] > L[Rmq[k][a + sh]])
        sol = Rmq[k][a + sh];

    g<<H[sol]<<'\n';
}
int main()
{
    int x,y;
    citire();
    dfs(1,0);
    rmq();
    for (int i=1;i<=M;i++)
    {
        f>>x>>y;
        lca(x,y);
    }
}