Cod sursa(job #1946762)

Utilizator MaligMamaliga cu smantana Malig Data 30 martie 2017 14:03:30
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.71 kb
#include <iostream>
#include <fstream>
#include <cmath>
#include <vector>
#include <algorithm>

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

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

int N,M,nrP;
int p[2*NMax],lg[2*NMax],poz[NMax],depth[NMax],mn[2*NMax][20];
vector<int> v[NMax];

void dfs(int,int);

int main()
{
    in>>N>>M;
    for (int i=2;i<=N;++i) {
        int dad;
        in>>dad;
        v[dad].push_back(i);
    }
    dfs(1,0);

    lg[1] = 0;
    mn[1][0] = p[1];
    for (int i=2;i<=nrP;++i) {
        lg[i] = lg[i/2] + 1;
        mn[i][0] = p[i];
    }

    for (int e=1;(1<<e) <= nrP; ++e) {

        for (int i=1;i + (1<<e) - 1 <= nrP; ++i) {
            int n1 = mn[i][e-1],
                n2 = mn[i + (1<<(e-1))][e-1];
            if (depth[n1] < depth[n2]) {
                mn[i][e] = n1;
            }
            else {
                mn[i][e] = n2;
            }
        }
    }

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

        int i = poz[a],j = poz[b];
        if (i > j) { swap(i,j); }

        int pt = lg[j-i+1],
            n1 = mn[i][pt],
            n2 = mn[j - (1<<pt) + 1][pt],
            val;
        if (depth[n1] < depth[n2]) {
            val = n1;
        }
        else {
            val = n2;
        }

        out<<val<<'\n';
    }
    in.close();out.close();
    return 0;
}

void dfs(int n,int d) {
    p[++nrP] = n;
    poz[n] = nrP;
    depth[n] = depth[d] + 1;

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

        dfs(son,n);
        p[++nrP] = n;
    }
}