Cod sursa(job #1967174)

Utilizator MithrilBratu Andrei Mithril Data 16 aprilie 2017 00:18:20
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.08 kb
#include <bits/stdc++.h>
#define NMAX 100005
#define LGMAX 18

using namespace std;

ifstream fin("lca.in");
ofstream fout("lca.out");
int n,m;
int lev[NMAX];
int dp[LGMAX][NMAX];
vector<int> g[NMAX];

void dfs(int n,int l) {
    lev[n]=l;
    for(auto& q:g[n])
        dfs(q,l+1);
}

int lca(int x,int y) {
    if(lev[x]<lev[y]) swap(x,y);

    int log1,log2;
    for(log1=0;(1<<log1)<lev[x];log1++);
    for(log2=0;(1<<log2)<lev[y];log2++);

    for(int k=log1;k>=0;k--) {
        if(lev[x]-(1<<k)>=lev[y]) {
            x=dp[k][x];
        }
    }

    if(x==y) return y;

    for(int k=log2;k>=0;k--) {
        if(dp[k][x]&&dp[k][x]!=dp[k][y]) {
            x=dp[k][x];
            y=dp[k][y];
        }
    }

    return dp[0][x];
}

int main()
{
    fin>>n>>m;
    for(int i=2;i<=n;i++) {
        fin>>dp[0][i];
        g[dp[0][i]].push_back(i);
    }
    dfs(1,1);
    for(int i=1;i<=LGMAX;i++) {
        for(int j=1;j<=n;j++) {
            dp[i][j]=dp[i-1][dp[i-1][j]];
        }
    }
    for(int i=1;i<=m;i++) {
        int x,y;
        fin>>x>>y;
        fout<<lca(x,y)<<'\n';
    }
    return 0;
}