Cod sursa(job #1905471)

Utilizator DenisONIcBanu Denis Andrei DenisONIc Data 6 martie 2017 08:30:15
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.27 kb
#include <fstream>
#include <cstdio>
#include <cmath>
#include <vector>
#define Nmax 100001
using namespace std;

ofstream g("lca.out");

int n,t[Nmax],st[Nmax],lg,m;
pair<int,int> rmq[18][2*Nmax];
vector<int> V[Nmax];


void dfs(int nod,int niv)
{
    rmq[0][++lg] = make_pair(nod,niv);
    st[nod] = lg;
    for (int i=0;i<V[nod].size();i++)
    {
        dfs(V[nod][i],niv+1);
        rmq[0][++lg] = make_pair(nod,niv);
    }
}

int lca(int x,int y)
{
    int l = log2(y-x+1);
    if (rmq[l][x].second<rmq[l][y-(1<<l)+1].second)
        return rmq[l][x].first;
    return rmq[l][y-(1<<l)+1].first;
}

int main()
{
    freopen("lca.in","r",stdin);
    scanf("%d%d",&n,&m);

    for (int i=2;i<=n;i++)
    {
        scanf("%d",&t[i]);
        V[t[i]].push_back(i);
    }

    dfs(1,1);

    int mx = log2(lg);
    for (int i=1;i<=mx;i++)
        for (int j=1;j<= lg-(1<<i)+1;j++)
        {
            if (rmq[i-1][j].second<rmq[i-1][j+(1<<(i-1))].second)
                rmq[i][j] = rmq[i-1][j];
            else
                rmq[i][j] = rmq[i-1][j+(1<<(i-1))];
        }

    for (int i=1;i<=m;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        g<<lca(min(st[x],st[y]),max(st[x],st[y]))<<'\n';
    }


    return 0;
}