Cod sursa(job #2667850)

Utilizator stefantagaTaga Stefan stefantaga Data 3 noiembrie 2020 23:17:34
Problema Lowest Common Ancestor Scor 30
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.53 kb
#include <bits/stdc++.h>

using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");
int nr=0,primloc[100005],acum[100005],niv[100005],n,m,i,x,y,rmq[18][100005];
vector <int> v[100005];
void dfs (int x,int nivel)
{
    int j;
    nr++;
    if (primloc[x]==0)
    {
        primloc[x]=nr;
    }
    acum[nr]=x;
    niv[nr]=nivel;
    for (j=0;j<v[x].size();j++)
    {
        int nod=v[x][j];
        dfs(nod,nivel+1);
        nr++;
        acum[nr]=x;
        niv[nr]=nivel;
    }
}
int lca (int x,int y)
{
    x=primloc[x];
    y=primloc[y];
    if (x>y)
    {
        swap(x,y);
    }
    if (x==y)
    {
        return acum[x];
    }
    int k=y-x+1;
    int lg=log2(k);
    if (niv[rmq[lg][x]]>niv[rmq[lg][y-(1<<lg)+1]])
    {
        return acum[rmq[lg][y-(1<<lg)+1]];
    }
    else
    {
        return acum[rmq[lg][x]];
    }
}
int lg,putere,j;
int main()
{
    f>>n>>m;
    for (i=2;i<=n;i++)
    {
        f>>x;
        v[x].push_back(i);
    }
    dfs(1,1);
    for (i=1;i<=nr;i++)
    {
        rmq[0][i]=i;
    }
    lg=log2(nr);
    for (i=1;i<=lg;i++)
    {
        putere=(1<<(i-1));
        for (j=1;j+putere*2<=nr;j++)
        {
            if (niv[rmq[i-1][j]]>niv[rmq[i-1][j+putere]])
            {
                rmq[i][j]=rmq[i-1][j+putere];
            }
            else
            {
                rmq[i][j]=rmq[i-1][j];
            }
        }
    }
    for (j=1;j<=m;j++)
    {
        f>>x>>y;
        g<<lca(x,y)<<'\n';
    }
    return 0;
}