Cod sursa(job #1921396)

Utilizator razvan242Zoltan Razvan-Daniel razvan242 Data 10 martie 2017 12:32:33
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.83 kb
#include <fstream>
#include <vector>

using namespace std;

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

const int LGMAX = 17;
const int NMAX = 1e5 + 1;

int n, q;
int a[NMAX];
int rmq[LGMAX][NMAX];
int pos[NMAX], lg[NMAX];
pair<int, int> euler[3 * NMAX]; // node, level
int eulerSZ;
vector<vector<int> > v;

inline void read() {
    fin >> n >> q;
    v = vector<vector<int> >(n + 1);
    int x;
    for (int i = 2; i <= n; ++i) {
        fin >> x;
        v[x].push_back(i);
    }
}

void dfs(int node, int lv) {
    euler[++eulerSZ] = {node, lv};
    pos[node] = eulerSZ;

    for (const int& other: v[node]) {
        dfs(other, lv + 1);
        euler[++eulerSZ] = {node, lv};
    }
}
inline void preProcess() {
    for (int i = 2; i <= eulerSZ; ++i)
        lg[i] = lg[i / 2] + 1;

    for (int i = 1; i <= eulerSZ; ++i)
        rmq[0][i] = i;
}

inline void getRMQ() {
    preProcess();
    int len;
    for (int i = 1; (1 << i) <= eulerSZ; ++i) {
        for (int j = 1; j + (1 << i) - 1 <= eulerSZ; ++j) {
            len = 1 << (i - 1);
            if (euler[rmq[i - 1][j]].second < euler[rmq[i - 1][j + len]].second)
                rmq[i][j] = rmq[i - 1][j];
            else
                rmq[i][j] = rmq[i - 1][j + len];
        }
    }
}

inline int getLCA(int x, int y) {
    int a = pos[x], b = pos[y];
    if (a > b)
        swap(a, b);
    int d = b - a + 1;
    int len = lg[d];
    int rem = d - (1 << len);
    if (euler[rmq[len][a]].second < euler[rmq[len][a + rem]].second)
        return euler[rmq[len][a]].first;
    else
        return euler[rmq[len][a + rem]].first;
}

int main()
{
    read();
    dfs(1, 0);
    getRMQ();
    int x, y;
    for (int i = 1; i <= q; ++i) {
        fin >> x >> y;
        fout << getLCA(x, y) << '\n';
    }
    return 0;
}