Cod sursa(job #3164321)

Utilizator GavrilaVladGavrila Vlad GavrilaVlad Data 2 noiembrie 2023 18:23:50
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.17 kb
//LCA cu smenul de la heavypath O(N + M log N)
#include <cstdio>
#include <vector>

using namespace std;

#define maxn 100010

int l[maxn], niv[maxn], d[maxn], tl[maxn];
int nl, n, m, x, y;
vector<int> v[maxn];

void df(int nod)
{
    d[nod]=1;
    if(v[nod].size()==0)
    {
        l[nod]=++nl;
        return;
    }

    int fmax, it, dmax=0;

    for(int i=0; i<v[nod].size(); ++i)
    {
        it=v[nod][i];
        niv[it]=niv[nod]+1;
        df(it);
        d[nod]+=d[it];
        if(d[it]>dmax)
        {
            dmax=d[it];
            fmax=(it);
        }
        tl[l[it]]=nod;
    }

    l[nod]=l[fmax];
}

int solve(int x, int y)
{
    while(l[x]!=l[y])
    {
        if(niv[tl[l[x]]]>niv[tl[l[y]]])
            x=tl[l[x]];
        else
            y=tl[l[y]];
    }

    if(niv[x]<niv[y])
        return x;
    return y;
}

int main()
{
    freopen("lca.in", "r", stdin);
    freopen("lca.out", "w", stdout);

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

    niv[1]=1;
    df(1);
    tl[l[1]]=0;

    while(m--)
    {
        scanf("%d%d", &x, &y);
        printf("%d\n", solve(x, y));
    }

    return 0;
}