Cod sursa(job #2417197)

Utilizator RazvanPanaiteRazvan Panaite RazvanPanaite Data 29 aprilie 2019 10:27:20
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.32 kb
#include <bits/stdc++.h>
#define DMAX 100010
#define LogDMAX 25

using namespace std;

ifstream fin("lca.in");
ofstream fout("lca.out");

vector <int> V[DMAX];

int M[2*DMAX][LogDMAX];
int nivel[DMAX];
int euler[2*DMAX];
int ap[DMAX];

int n,query,cate;

void dfs(int node,int nivel);
void rmq(int n);

int main(){
    int i,tata,x,y,k,aux;
    fin>>n>>query;
    for(i=2;i<=n;i++){
        fin>>tata;
        V[tata].push_back(i);
    }
    dfs(1,1);
    rmq(cate);
    while(query--){
        fin>>x>>y;
        x=ap[x];
        y=ap[y];
        if(x>y){
           aux=x;
           x=y;
           y=aux;
        }
        k=log2(y-x+1);
        if(nivel[M[x][k]]<nivel[M[y-(1<<k)+1][k]])
           fout<<M[x][k]<<'\n';
           else
           fout<<M[y-(1<<k)+1][k]<<'\n';
    }
    return 0;
}
void dfs(int node,int niv){
    nivel[node]=niv;
    euler[++cate]=node;
    ap[node]=cate;
    for(auto& i:V[node]){
        dfs(i,niv+1);
        euler[++cate]=node;
    }
}
void rmq(int n){
    int i,j;
    for(i=1;i<=n;i++)
        M[i][0]=euler[i];
    for(j=1;(1<<j)<=n;j++)
        for(i=1;i+(1<<j)-1<=n;i++)
            if(nivel[M[i][j-1]]<nivel[M[i+(1<<(j-1))][j-1]])
               M[i][j]=M[i][j-1];
               else
               M[i][j]=M[i+(1<<(j-1))][j-1];
}