Cod sursa(job #1637213)

Utilizator Burbon13Burbon13 Burbon13 Data 7 martie 2016 15:53:10
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.44 kb
#include <cstdio>
#include <vector>
#include <cmath>

using namespace std;

const int nmx = 100005;

int n,m,pos[2*nmx];
vector <int> g[nmx];
vector <pair<int,int> > euler;
pair <int,int> dp[20][2*nmx]; ///nod nivel

void citire(){
    scanf("%d %d", &n, &m);
    int tata;
    for(int i = 2; i <= n; ++i){
        scanf("%d", &tata);
        g[tata].push_back(i);
    }
}

void dfs(int nod, int niv){
    euler.push_back(make_pair(niv,nod));
    pos[nod] = euler.size();
    for(vector<int>::iterator it = g[nod].begin(); it != g[nod].end(); ++it){
        dfs(*it,niv+1);
        euler.push_back(make_pair(niv,nod));
    }
}

void rmq(){
    int n = euler.size();
    for(int i = 1; i <= n; ++i)
        dp[0][i] = euler[i-1];
    for(int i = 1; (1 << i) < n; ++i)
        for(int j = 1; j + (1 << i) < n; ++j)
            dp[i][j] = min(dp[i-1][j],dp[i-1][j+(1<<(i-1))]);
}

void query(){
    int nod1,nod2;
    int diff,x,y,k;
    pair <int,int> r;
    for(int i = 1; i <= m; ++i){
        scanf("%d %d", &nod1, &nod2);
        x = pos[nod1];
        y = pos[nod2];
        diff = y - x + 1;
        if(diff < 0)
            diff *= -1;
        k = log2(diff);
        r = min(dp[k][x],dp[k][y-(1<<k)+1]);
        printf("%d\n", r.second);
    }
}

int main(){
    freopen("lca.in", "r", stdin);
    freopen("lca.out", "w", stdout);
    citire();
    dfs(1,0);
    rmq();
    query();
    return 0;
}