Cod sursa(job #2499351)

Utilizator AlexPascu007Pascu Ionut Alexandru AlexPascu007 Data 25 noiembrie 2019 22:25:18
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.39 kb
#include <bits/stdc++.h>
#define DIM 200010
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
int n,m,i,j,k,e[DIM],f[DIM],niv[DIM],putere,x,y,l[25],p[25],d[25][DIM];
vector<int> L[DIM];
void euler(int nod,int nivel) { //reprezentarea euler a arborelui
    e[++k]=nod, niv[k]=nivel, f[nod]=k;
    for (int i=0;i<L[nod].size();i++) {
        int vecin=L[nod][i];
        euler(vecin,nivel+1);
        e[++k]=nod, niv[k]=nivel;
    }
}
int main() {
    fin>>n>>m;
    for (i=2;i<=n;i++) {
        fin>>x;
        L[x].push_back(i);
    }
    euler(1,1);
    for (i=2;i<=k;i++)
        l[i]=l[i/2]+1;
    for (i=1;i<=k;i++)
        d[0][i]=i;
    for (i=1;i<=l[k];i++) { //cu rmq calculam nivelul minim din orice interval
        for (j=1;j<=k;j++) {
            d[i][j]=d[i-1][j];
            if (j+(1<<(i-1))<=k&&niv[d[i][j]]>niv[d[i-1][j+(1<<(i-1))]])
                d[i][j]=d[i-1][j+(1<<(i-1))];
        }
    }
    while (m--) {
        fin>>x>>y;
        x=f[x], y=f[y]; //prima pozitie in care apar x si y in reprezentarea euler
        if (x>y)
            swap(x,y);
        putere=l[y-x+1];
        //LCA este nodul cu nivelul minim din intervalul [x,y]
        if (niv[d[putere][x]]<niv[d[putere][y-(1<<putere)+1]])
            fout<<e[d[putere][x]]<<"\n";
        else
            fout<<e[d[putere][y-(1<<putere)+1]]<<"\n";
    }
    return 0;
}