Cod sursa(job #1951452)

Utilizator MaligMamaliga cu smantana Malig Data 3 aprilie 2017 17:01:41
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.75 kb
#include <iostream>
#include <fstream>
#include <cmath>
#include <vector>
#include <string.h>

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

const int NMax = 1e6 + 5;
const int inf = 2e9 + 5;
typedef long long ll;

int N,M,H,sq;
int depth[NMax],dad[NMax],ancestor[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) {
        int d;
        in>>d;
        v[d].push_back(i);
        dad[i] = d;
    }

    //depth[1] = -1;
    dfs(1);
    for (sq=1;sq*sq <= H;++sq) ;
    --sq;
    build(1);

    //cout<<dad[5];

    while (M--) {
        int x,y;
        in>>x>>y;
        out<<query(x,y)<<'\n';
    }
    in.close();out.close();
    return 0;
}

void dfs(int n) {
    int d = dad[n];
    depth[n] = depth[d] + 1;

    if (H < depth[n]) {
        H = depth[n];
    }

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

        dfs(son);
    }
}

void build(int n) {
    int d = dad[n];
    if (depth[n] % sq == 1) {
        ancestor[n] = d;
    }
    else {
        ancestor[n] = ancestor[d];
    }

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

        build(son);
    }
}

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

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

    while (x != y) {
        x = dad[x];
        y = dad[y];
    }

    return x;
}