Cod sursa(job #1982515)

Utilizator MaligMamaliga cu smantana Malig Data 19 mai 2017 08:59:07
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.73 kb
#include <iostream>
#include <fstream>
#include <math.h>
#include <algorithm>
#include <cstdlib>
#include <time.h>
#include <vector>

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

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

int N,M,H,root;
int dad[NMax],an[NMax],depth[NMax];
bool vis[NMax];
vector<int> v[NMax];

void dfs(int);
void build(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);
    for (int i=1;i <= N;++i) {
        vis[i] = false;
    }

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

    build(1);

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

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

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

void dfs(int node) {
    vis[node] = true;
    depth[node] = depth[dad[node]] + 1;
    H = max(H,depth[node]);

    for (auto nxt : v[node]) {
        if (vis[nxt]) {
            continue;
        }

        dfs(nxt);
    }
}

void build(int node) {
    if (depth[node] % root == 1) {
        an[node] = dad[node];
    }
    else {
        an[node] = an[dad[node]];
    }

    vis[node] = true;

    for (auto nxt : v[node]) {
        if (vis[nxt]) {
            continue;
        }

        build(nxt);
    }
}

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

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

    return a;
}