Cod sursa(job #1815965)

Utilizator CTI_KnightCir Constantin CTI_Knight Data 25 noiembrie 2016 23:05:40
Problema Lowest Common Ancestor Scor 90
Compilator cpp Status done
Runda Arhiva educationala Marime 1.51 kb
// CTI

#include <cstdio>
#include <algorithm>
#include <vector>
#include <stack>
#include <string>
#include <cmath>

using namespace std;

vector <int> a[100010];
int t[100010], l[100010], tata[100010]; // tata in arbore, nivel, tata sectiune precedenta

int mod;    // dimensiune sectiune

void dfs(int nod, int tnod, int nivel) {
    l[nod]    = nivel;
    if (nivel < mod) {  // prima sectiune - tata este radacina
        tata[nod] = 1;
    } else {
        if (nivel % mod) {  // inceputul sectiunii
            tata[nod] = tnod;
        } else {
            tata[nod] = tata[tnod];
        }
    }

    for (int i = 0; i < a[nod].size(); ++i) {
        dfs(a[nod][i], nod, nivel + 1);
    }
}

int LCA(int x, int y) {
    while (tata[x] != tata[y]) {    // cautam sectiunea
        if (l[x] > l[y]) {
            x = tata[x];
        } else {
            y = tata[y];
        }
    }

    while (x != y) {                // cautam tatal in arbore
        if (l[x] > l[y]) {
            x = t[x];
        } else {
            y = t[y];
        }
    }

    return x;
}

int main()
{
    freopen("lca.in","r",stdin);
    freopen("lca.out","w",stdout);

    int n, q;
    scanf("%d%d", &n, &q);
    mod = 200;
    for (int i = 2; i <= n; ++i) {
        scanf("%d", &t[i]);
        a[t[i]].push_back(i);
    }

    dfs(1, 0, 0);

    for (int i = 0; i < q; ++i) {
        int x, y;
        scanf("%d%d", &x, &y);
        printf("%d\n", LCA(x, y));
    }

    return 0;
}