Cod sursa(job #1936195)

Utilizator MaligMamaliga cu smantana Malig Data 22 martie 2017 21:59:15
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.51 kb
#include <iostream>
#include <fstream>
#include <vector>

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

const int NMax = 1e5 + 5;

int N,M,H,root;
int dad[NMax],level[NMax],an[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]].push_back(i);
    }

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

    build(1,1);

    /*
    for (int i=1;i<=N;++i) {
        out<<dad[i]<<' ';
    }
    out<<'\n';
    //*/

    while (M--) {
        int x,y;
        in>>x>>y;
        if (level[x] < level[y]) {
            swap(x,y);
        }

        out<<query(x,y)<<'\n';
    }
    return 0;
}

void dfs(int x,int d) {
    if (H < d) {
        H = d;
    }
    level[x] = d;

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

void build(int x,int d) {
    if (d % root == 1) {
        an[x] = dad[x];
    }
    else {
        an[x] = an[dad[x]];
    }

    for (int k=0;k<v[x].size();++k) {
        build(v[x][k],d+1);
    }
}

int query(int x,int y) {
    while (an[x] != an[y]) {
        if (level[x] > level[y]) {
            x = an[x];
        }
        else {
            y = an[y];
        }
    }

    while (x != y) {
        if (level[x] > level[y]) {
            x = dad[x];
        }
        else {
            y = dad[y];
        }
    }
    return x;
}