Cod sursa(job #2120323)

Utilizator georgerapeanuRapeanu George georgerapeanu Data 2 februarie 2018 12:17:44
Problema Lowest Common Ancestor Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 1.68 kb
#include <cstdio>
#include <iostream>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;
FILE *f = fopen("lca.in","r");
FILE *g = fopen("lca.out","w");
vector<int> G[100005];
vector<int> mark[100005];
int N,K,T;
int len;
int euler[200005];
bool U[100005];
bool vizU[100005];
int lvl[100005];
int RMQ[18][200005];
int Ta[100005];
int fst[100005];
int lst[100005];
void dfs(int nod,int tata){
    lvl[nod] = lvl[tata] + 1;
    Ta[nod] = tata;
    euler[++len] = nod;
    RMQ[0][len] = nod;
    fst[nod] = len;
    for(auto it:G[nod]){
        if(it != tata){
            dfs(it,nod);
            euler[++len] = nod;
            RMQ[0][len] = nod;
        }
    }
    lst[nod] = len;
}
int better(int u,int v){
    if(lvl[u] < lvl[v]){
        return u;
    }
    return v;
}
void prelca(){
    for(int i = 1;i <= 17;i++){
        for(int j = 1;j <= len;j++){
            if(j >= (1 << (i - 1))){
                RMQ[i][j] = better(RMQ[i - 1][j],RMQ[i - 1][j - (1 << (i - 1))]);
            }
        }
    }
}
int lca(int u,int v){
    if(fst[u] > fst[v]){
        swap(u,v);
    }
    int lg = 0;
    while(fst[v] - fst[u] >= (1 << lg)){
        lg++;
    }
    lg--;
    return better(RMQ[lg][fst[v]],RMQ[lg][fst[u] + (1 << lg) - 1]);
}
int main(){
    fscanf(f,"%d %d",&N,&K);
    for(int i = 2;i <= N;i++){
        int x;
        fscanf(f,"%d",&x);
        G[x].push_back(i);
        G[i].push_back(x);
    }
    dfs(1,0);
    prelca();
    for(int i = 1;i <= K;i++){
        int u,v;
        fscanf(f,"%d %d",&u,&v);
        fprintf(g,"%d\n",lca(u,v));
    }
    fclose(f);
    fclose(g);
    return 0;
}