Cod sursa(job #1940363)

Utilizator radu.leonardoThe Doctor radu.leonardo Data 26 martie 2017 16:11:41
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.35 kb
#include <bits/stdc++.h>
using namespace std;
int n,m,k=0;
vector <int> G[100001];
int Euler[200001],Depth[200001],First[200001];
int LOG[200001],RMQ[20][200001];
ifstream f("lca.in");
ofstream g("lca.out");

void read_data()
{
    f>>n>>m;
    for(int i=1; i<n; i++)
    {
        int x;
        f>>x;
        G[x].push_back(i+1);
    }
}

void DFS(int node,int level=0)
{
    Euler[++k]=node;
    Depth[k]=level;
    First[node]=k;

    for(auto it:G[node])
        DFS(it,level+1),
            Euler[++k]=node,
                       Depth[k]=level;
}

void buildRMQ()
{
    for(int i=2; i<=k; ++i) LOG[i] = LOG[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)
            if(Depth[RMQ[i-1][j+(1<<(i-1))]]<Depth[RMQ[i-1][j]]) RMQ[i][j] = RMQ[i-1][j + (1<<(i-1))];
            else RMQ[i][j] = RMQ[i-1][j];
}

void compute()
{
    DFS(1);
    buildRMQ();
}

int LCA(int x,int y)
{
    int a=min(First[x],First[y]);
    int b=max(First[x],First[y]);
    int l=LOG[b-a+1];
    if(Depth[RMQ[l][a]]>Depth[RMQ[l][b+1-(1<<l)]]) return Euler[RMQ[l][b+1-(1<<l)]];
    else                                           return Euler[RMQ[l][a]];
}

void solve()
{
    int x,y;
    for(int i=1; i<=m; i++)
    {
        f>>x>>y;
        g<<LCA(x,y)<<'\n';
    }
}

int main()
{
    read_data();
    compute();
    solve();
}