Cod sursa(job #1882866)

Utilizator tudormaximTudor Maxim tudormaxim Data 17 februarie 2017 15:56:20
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.59 kb
#include <bits/stdc++.h>
using namespace std;

ifstream fin ("lca.in");
ofstream fout ("lca.out");

const int maxn = 1e5 + 5;
vector <int> G[maxn];
int minn, ans, m;
int Euler[maxn << 1], Lev[maxn << 1], T[maxn << 2], First[maxn];

void Dfs (int node, int lev) {
    Euler[++m] = node;
    Lev[m] = lev;
    First[node] = m;
    for (auto &it : G[node]) {
        Dfs(it, lev + 1);
        Euler[++m] = node;
        Lev[m] = lev;
    }
}

inline int Unite (int x, int y) {
    if (Lev[x] <= Lev[y]) return x;
    return y;
}

void Build () {
    int i;
    for (i = 1; i <= m; i++) {
        T[i + m - 1] = i;
    }
    for (i = m - 1; i > 0; i--) {
        T[i] = Unite(T[i << 1], T[i << 1 | 1]);
    }
}

inline void Get_sol (int x) {
    if (Lev[x] < minn) {
        minn = Lev[x];
        ans = Euler[x];
    }
}

void Query (int left, int right) {
    left += m;
    right += m;
    while (left < right) {
        if (left & 1) Get_sol(T[left++]);
        if (right & 1) Get_sol(T[--right]);
        left >>= 1;
        right >>= 1;
    }
}

int Lca (int x, int y) {
    int a = First[x];
    int b = First[y];
    if (a > b) swap(a, b);
    minn = (1 << 30);
    Query(a - 1, b);
    return ans;
}

int main () {
    ios_base :: sync_with_stdio (false);
    int n, q, i, x, y;
    fin >> n >> q;
    for (i = 2; i <= n; i++) {
        fin >> x;
        G[x].push_back(i);
    }
    Dfs(1, 1);
    Build();
    while (q--) {
        fin >> x >> y;
        fout << Lca(x, y) << '\n';
    }
    fin.close();
    fout.close();
    return 0;
}