Cod sursa(job #2693389)

Utilizator mjmilan11Mujdar Milan mjmilan11 Data 5 ianuarie 2021 18:42:47
Problema Lowest Common Ancestor Scor 20
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.28 kb
#include <bits/stdc++.h>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
const int NMAX = 400005;
int nxt[NMAX],lg2[NMAX],rmq[21][NMAX],euler[NMAX],tata[NMAX];
int first[NMAX],niv[NMAX],last[NMAX],x,y,k,n,m;
int lca(int x,int y){
    int fx=first[x];
    int fy=first[y];
    if(fx>fy) swap(fx,fy);
    int lg=lg2[fy-fx+1];
    int rasp=rmq[lg][fx+(1<<lg)-1];
    if(niv[rmq[lg][fy]]<niv[rasp]) rasp=rmq[lg][fy];
    return rasp;
}
void dfs(int nod){
    euler[++k]=nod;
    niv[nod]=niv[tata[nod]]+1;
    first[nod]=k;
    for(int i=last[nod];i!=0;i=nxt[i]){
        if(first[i+1]==0){
            dfs(i+1);
            euler[++k]=nod;
        }
    }
}
int main()
{
    fin >> n >> m;
    for(int i=2;i<=n;i++) lg2[i]=lg2[i/2]+1;
    for(int i=2;i<=n;i++){
        fin >> x;
        tata[i]=x;
        nxt[i-1]=last[x];
        last[x]=i-1;
    }
    dfs(1);
    for(int i=1;i<=k;i++) rmq[0][i]=euler[i];
    for(int i=1;i<=20;i++){
        for(int j=1<<i;j<=2*n;j++){
            rmq[i][j]=rmq[i-1][j];
            x=rmq[i-1][j-(1<<(i-1))];
            if(niv[x]<niv[rmq[i][j]])
                rmq[i][j]=x;
        }
    }
    for(int i=1;i<=m;i++){
        fin >> x >> y;
        fout << lca(x,y) << '\n';
    }
    return 0;
}