Cod sursa(job #1998768)

Utilizator savigunFeleaga Dragos-George savigun Data 9 iulie 2017 00:30:38
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.75 kb
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;


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

const int MAXN = 1e5 + 5;
int n, m, nop;
int level[MAXN], parent[MAXN], whatPath[MAXN], whatPos[MAXN], size[MAXN];
vector<int> g[MAXN], paths[MAXN];


void set_path(int x, int p) {
    whatPath[x] = p;
    whatPos[x] = paths[p].size();
    paths[p].push_back(x);
}

void HPD(int x, int depth) {
    level[x] = depth;
    if (g[x].size() == 0) {
        size[x] = 1;
        nop++;
        set_path(x, nop);
    } else {
        int max_size = 0, max_path;
        size[x] = 1;

        for (int i = 0; i < g[x].size(); ++i) {
            int y = g[x][i];
            HPD(y, depth + 1);
            size[x] += size[y];
            if (size[y] > max_size) {
                max_size = size[y];
                max_path = whatPath[y];
            }
        }

        set_path(x, max_path);
    }
}


int query(int x, int y) {
    int xPathParent = paths[whatPath[x]][paths[whatPath[x]].size() - 1];
    int yPathParent = paths[whatPath[y]][paths[whatPath[y]].size() - 1];

    while (whatPath[x] != whatPath[y]) {
        if (level[xPathParent] < level[yPathParent]) {
            swap(x, y);
            swap(xPathParent, yPathParent);
        }

        x = parent[xPathParent];
        xPathParent = paths[whatPath[x]][paths[whatPath[x]].size() - 1];
    }

    return (level[x] < level[y]) ? x : y;
}


int main()
{
    in >> n >> m;
    for (int i = 2, x; i <= n; ++i) {
        in >> x;
        parent[i] = x;
        g[x].push_back(i);
    }

    HPD(1, 1);

    for (int i = 1, x, y; i <= m; ++i) {
        in >> x >> y;
        out << query(x, y) << "\n";
    }

    return 0;
}