Cod sursa(job #1537866)

Utilizator lupvasileLup Vasile lupvasile Data 28 noiembrie 2015 11:20:50
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.42 kb
#include <bits/stdc++.h>

using namespace std;

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

#define nmax 100010

#ifdef INFOARENA
#define cout fout
#endif // INFOARENA

int rmq[20][nmax<<1],first[nmax];
int lev[nmax],E[nmax<<1],lg[nmax<<1];
int n,m,lgmax,cnt;
vector<int> G[nmax];

void read()
{
    int x,i;
    fin>>n>>m;
    for(i=2;i<=n;++i)
    {
        fin>>x;
        G[x].push_back(i);
    }
}

void dfs(int nod,int level)
{
    lev[nod]=level;
    E[++cnt]=nod;
    first[nod]=cnt;

    for(auto it:G[nod])
    {
        dfs(it,level+1);
        E[++cnt]=nod;
    }
}

void make_rmq()
{
    int i,k;
    for(i=2;i<=cnt;++i) lg[i]=lg[i>>1]+1;

    lgmax=lg[cnt]+1;

    for(i=1;i<=cnt;++i) rmq[0][i]=E[i];

    for(k=1;k<=lgmax;++k)
        for(i=1;i<=cnt;++i)
        {
            rmq[k][i]=rmq[k-1][i];
            if(lev[rmq[k][i]]>lev[rmq[k-1][i+(1<<(k-1))]])
                rmq[k][i]=rmq[k-1][i+(1<<(k-1))];
        }
}

int lca(int x,int y)
{
    int diff=first[y]-first[x]+1;
    int log=lg[diff];

    if(lev[rmq[log][first[x]]]<lev[rmq[log][first[y]-(1<<log)+1]])
    return rmq[log][first[x]];
    return rmq[log][first[y]-(1<<log)+1];
}

int main()
{
    int x,y;
    read();
    dfs(1,1);
    make_rmq();

    for(;m;--m)
    {
        fin>>x>>y;
        if(first[x]>first[y]) swap(x,y);
        cout<<lca(x,y)<<'\n';
    }
    return 0;
}