Cod sursa(job #1690057)

Utilizator lupvasileLup Vasile lupvasile Data 14 aprilie 2016 18:46:22
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.38 kb
#include <bits/stdc++.h>
using namespace std;
#ifdef INFOARENA
#define cout fout
ifstream fin("lca.in");
ofstream fout("lca.out");
#else
ifstream fin("date.in");
#endif // INFOARENA

/// ///////////////////////////////////////////

void read();

#define nmax 100010
#define inf 0x3f3f3f3f
#define logmax 17

int dad[logmax][nmax],n,lev[nmax],m;
vector<int> G[nmax];

void make_dads()
{
    int k,i;
    for(k=1;(1<<k)<n;++k)
        for(i=2;i<=n;++i)
            dad[k][i]=dad[k-1][dad[k-1][i]];
}

int lca(int x,int y)
{

    if(lev[x]<lev[y]) swap(x,y);
    int diff=lev[x]-lev[y];

    for(int k=0;(1<<k)<=diff;++k)
        if((1<<k) & diff)
            x=dad[k][x];

    if(x==y) return x;

    int step;
    for(step=1;(1<<step)<=n;step++);
    --step;

    for(;step>=0;--step)
    {
        if(dad[step][x]!=dad[step][y])
            x=dad[step][x],y=dad[step][y];
    }

    return dad[0][x];
}

void dfs(int nod)
{
    ++lev[nod];
    for(auto son:G[nod])
    {
        lev[son]=lev[nod];
        dfs(son);
    }
}

int main()
{
    read();

    dfs(1);

    make_dads();

    int x,y;
    for(;m;--m)
    {
        fin>>x>>y;
        cout<<lca(x,y)<<'\n';
    }
}
void read()
{
    int x,y,c,i;
    fin>>n>>m;
    for(i=2;i<=n; ++i)
    {
        fin>>x;
        dad[0][i]=x;
        G[x].push_back(i);
    }
}