Cod sursa(job #3185824)

Utilizator Emilia23Dobra Emilia Emilia23 Data 20 decembrie 2023 16:16:22
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.52 kb
#include <bits/stdc++.h>
#define SIZE 100005
using namespace std;

ifstream f("lca.in");
ofstream g("lca.out");

int n,m,nivel[SIZE],poz[SIZE],e[2*SIZE],p[2*SIZE],t[SIZE],k;
vector<int>a[SIZE];

struct elem
{
    int nod,lvl;
}v[2*SIZE],rmq[20][2*SIZE];

void dfs(int nod)
{
    nivel[nod]=nivel[t[nod]]+1;
    v[++k].nod=nod;
    v[k].lvl=nivel[nod];
    for(auto u:a[nod])
    {
        dfs(u);
        v[++k].nod=nod;
        v[k].lvl=nivel[nod];
    }
}

void precalculare()
{
    int x,y=1;
    for(int i=1;i<=k;i++)rmq[0][i]=v[i];
    for(x=1;x*2<=k;x*=2)
    {
        for(int i=1;i<=k-2*x+1;i++)
            if(rmq[y-1][i].lvl<rmq[y-1][i+x].lvl)rmq[y][i]=rmq[y-1][i];
                else rmq[y][i]=rmq[y-1][i+x];
        y++;
    }
}

void rmqlca()
{
    precalculare();
    int x=1,y=0,i;
    for(i=1;i<=k;i++)
    {
        if(x*2<=i)x*=2,y++;
        p[i]=x;
        e[i]=y;
    }
}

int lca(int x,int y)
{
    x=poz[x];
    y=poz[y];
    if(x>y)swap(x,y);
    int aa=e[y-x+1],bb=p[y-x+1];
    if(rmq[aa][x].lvl<rmq[aa][y-bb+1].lvl)return rmq[aa][x].nod;
    else return rmq[aa][y-bb+1].nod;
}

int main()
{
    int i,x,y;
    f>>n>>m;
    for(i=2;i<=n;i++)
    {
        f>>t[i];
        a[t[i]].push_back(i);
    }
    dfs(1);
    rmqlca();
    //prima aparitie a fiecarui nod in reprezentarea Euler
    for(i=1;i<=k;i++)
        if(poz[v[i].nod]==0)poz[v[i].nod]=i;

    for(i=1;i<=m;i++)
    {
        f>>x>>y;
        g<<lca(x,y)<<'\n';
    }
    return 0;
}