Cod sursa(job #2763114)

Utilizator VladNANegoita Vlad-Andrei VladNA Data 11 iulie 2021 17:04:11
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.61 kb
#include <fstream>
#include <vector>
#define NMAX 100005
#define INF 1e9
#define PMAX 19
using namespace std;

ifstream cin("lca.in");
ofstream cout("lca.out");

int n,m,p;
int t[NMAX],e[2*NMAX],l[2*NMAX],h[NMAX],ad[NMAX];
vector<int>f[NMAX];
int rmq[2*NMAX][PMAX],lg[2*NMAX];

void dfs(int nod)
{
    ad[nod]=ad[t[nod]]+1;
    e[++p]=nod;
    l[p]=ad[nod];
    if(h[nod]==0)
        h[nod]=p;
    for(int fiu : f[nod])
    {
        dfs(fiu);
        e[++p]=nod;
        l[p]=ad[nod];
    }
}

int main()
{
    cin>>n>>m;
    for(int i=2;i<=n;i++)
    {
        cin>>t[i];
        f[t[i]].push_back(i);
    }
    ad[0]=0;
    dfs(1);
    l[0]=INF;
    lg[0]=-1;
    for(int i=1;i<=p;i++)
    {
        rmq[i][0]=i;
        lg[i]=lg[i/2]+1;
    }
    for(int put=1;(1 << put) <p;put++)
        for(int i=1;i+(1 << put)-1<=p;i++)
        {
            if(l[rmq[i][put-1]]<l[rmq[i][put]])
                rmq[i][put]=rmq[i][put-1];
            if(l[rmq[i+(1 << (put-1) )][put-1]]<l[rmq[i][put]])
                rmq[i][put]=rmq[i+( 1 << (put-1) )][put-1];
        }
    for(int i=1;i<=m;i++)
    {
        int x,y,L,dif,minim=INF,ind;
        cin>>x>>y;
        if(h[x]>h[y])
            swap(x,y);
        L=h[y]-h[x]+1;
        dif=L-(1 << lg[L]);
        if(minim>l[rmq[h[x]][lg[L]]])
        {
            minim=l[rmq[h[x]][lg[L]]];
            ind=rmq[h[x]][lg[L]];
        }
        if(minim>l[rmq[h[x]+dif][lg[L]]])
        {
            minim=l[rmq[h[x]+dif][lg[L]]];
            ind=rmq[h[x]+dif][lg[L]];
        }
        cout<<e[ind]<<'\n';
    }
    return 0;
}