Cod sursa(job #1973690)

Utilizator MaligMamaliga cu smantana Malig Data 25 aprilie 2017 18:33:37
Problema Lowest Common Ancestor Scor 90
Compilator cpp Status done
Runda Arhiva educationala Marime 1.54 kb
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");

#define pb push_back
typedef long long ll;
const int NMax = 1e5 + 5;

int N,M,H;
int dad[NMax],depth[NMax],ancestor[NMax];
vector<int> v[NMax];

void dfs(int,int);
void build(int,int);
int query(int,int);

int main() {
    in>>N>>M;
    for (int i=2;i<=N;++i) {
        in>>dad[i];
        v[dad[i]].pb(i);
    }

    dfs(1,1);

    int root = 1;
    for (;root * root <= H;++root) ;
    --root;

    build(1,1);

    while (M--) {
        int a,b;
        in>>a>>b;

        out<<query(a,b)<<'\n';
    }

    in.close();out.close();
    return 0;
}

void dfs(int nod,int dep) {
    depth[nod] = dep;

    if (H < dep) {
        H = dep;
    }

    for (int k=0;k < (int)v[nod].size();++k) {
        dfs(v[nod][k],dep+1);
    }
}

void build(int nod,int dep) {
    if (dep % H == 1) {
        ancestor[nod] = dad[nod];
    }
    else {
        ancestor[nod] = ancestor[dad[nod]];
    }

    for (int k=0;k < (int)v[nod].size();++k) {
        int next = v[nod][k];

        build(next,dep+1);
    }
}

int query(int a,int b) {
    while (ancestor[a] != ancestor[b]) {
        if (depth[a] > depth[b]) {
            a = dad[a];
        }
        else {
            b = dad[b];
        }
    }

    while (a != b) {
        if (depth[a] > depth[b]) {
            a = dad[a];
        }
        else {
            b = dad[b];
        }
    }

    return a;
}