Cod sursa(job #1973696)

Utilizator MaligMamaliga cu smantana Malig Data 25 aprilie 2017 18:39:44
Problema Lowest Common Ancestor Scor 90
Compilator cpp Status done
Runda Arhiva educationala Marime 1.58 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,root;
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);

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

    build(1,1);

    while (M--) {
        int a,b;
        in>>a>>b;
        if (depth[a] < depth[b]) {
            swap(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 % root == 1) {
        ancestor[nod] = dad[nod];
    }
    else {
        ancestor[nod] = ancestor[dad[nod]];
    }

    for (int k=0;k < (int)v[nod].size();++k) {
        build(v[nod][k],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;
}