Cod sursa(job #2817918)

Utilizator ElizaTElla Rose ElizaT Data 14 decembrie 2021 18:02:31
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.51 kb
#include <bits/stdc++.h>

using namespace std;

const int NMAX = 1e5,LOG = 20;
vector<int> fii[NMAX + 5];
int rmq[4 * NMAX + 5][LOG + 5],lg[4 * NMAX + 5],euler[NMAX * 4 + 5],level[NMAX * 4 + 5],first[NMAX * 4 + 5];
int n,cnt,ans,x,y,z;

void dfs(int node, int lvl) {
    euler[++cnt] = node;
    level[cnt] = lvl;
    first[node] = cnt;
    for (int i = 0;i < fii[node].size();i++) {
        dfs(fii[node][i], lvl + 1);
        euler[++cnt] = node;
        level[cnt] = lvl;
    }
}
void RMQ() {
    rmq[1][0] = 1;
    for (int i = 2;i <= cnt;i++) {
        lg[i] = lg[(i >> 1)] + 1;
        rmq[i][0] = i;
    }
    for (int j = 1;(1 << j) <= cnt;j++)
        for (int i = 1;i + (1 << (j - 1)) <= cnt;i++) {
            rmq[i][j] = rmq[i][j - 1];
            if (level[rmq[i + (1 << (j - 1))][j - 1]] < level[rmq[i][j]])
                rmq[i][j] = rmq[i + (1 << (j - 1))][j - 1];
        }
}
int lca(int a, int b) {
    x = first[a];
    y = first[b];
    if (x > y)
        swap(x, y);
    z = lg[y - x + 1];
    ans = rmq[x][z];
    if (level[rmq[y - (1 << z) + 1][z]] < level[ans])
        ans = rmq[y - (1 << z) + 1][z];
    return euler[ans];
}
int main()
{
    ifstream fin("lca.in");
    ofstream fout("lca.out");
    int m,a,b;
    fin >> n >> m;
    for (int i = 2;i <= n;i++) {
        fin >> a;
        fii[a].push_back(i);
    }
    dfs(1, 0);
    RMQ();
    for (int i = 0;i < m;i++) {
        fin >> a >> b;
        fout << lca(a, b) << '\n';
    }
    return 0;
}