Cod sursa(job #1921440)

Utilizator razvan242Zoltan Razvan-Daniel razvan242 Data 10 martie 2017 12:43:20
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.8 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];
int lev[2 * NMAX], nodes[2 * NMAX];
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) {
    lev[++eulerSZ] = lv;
    nodes[eulerSZ] = node;
    pos[node] = eulerSZ;

    for (const int& other: v[node]) {
        dfs(other, lv + 1);
        lev[++eulerSZ] = lv;
        nodes[eulerSZ] = node;
    }
}

inline void getRMQ() {
    for (int i = 2; i <= eulerSZ; ++i)
        lg[i] = lg[i / 2] + 1;
    for (int i = 1; i <= eulerSZ; ++i)
        rmq[0][i] = i;

    int len, R1, R2;
    for (int i = 1; (1 << i) <= eulerSZ; ++i) {
        for (int j = 1; j + (1 << i) - 1 <= eulerSZ; ++j) {
            len = 1 << (i - 1);
            R1 = rmq[i - 1][j];
            R2 = rmq[i - 1][j + len];
            if (lev[R1] < lev[R2])
                rmq[i][j] = R1;
            else
                rmq[i][j] = R2;
        }
    }
}

inline int getLCA(int x, int y) {
    int xx = pos[x], yy = pos[y];
    if (xx > yy)
        swap(xx, yy);
    int d = yy - xx + 1;
    int len = lg[d];
    int rem = d - (1 << len);
    int R1 = rmq[len][xx], R2 = rmq[len][xx + rem];
    if (lev[R1] < lev[R2])
        return nodes[R1];
    else
        return nodes[R2];
}


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;
}