Cod sursa(job #2833757)

Utilizator PopaMihaimihai popa PopaMihai Data 15 ianuarie 2022 16:57:28
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.5 kb
#include <bits/stdc++.h>

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

const int NMAX = 1e5 + 2;

int n, q;
int euler[2 * NMAX], tata[NMAX], Level[NMAX], lg[2 * NMAX], timp[NMAX];
int rmq[18][2 * NMAX];

vector <int> G[NMAX];

int minn(int x, int y)
{
    return (Level[x] < Level[y] ? x : y);
}

void dfs(int node, int level)
{
    euler[++euler[0]] = node;
    timp[node] = euler[0];
    Level[node] = level;
    for(auto it: G[node])
        dfs(it, level + 1), euler[++euler[0]] = node;
}

void buildRMQ()
{
    for(int i = 1; i <= euler[0]; i++)
        rmq[0][i] = euler[i];
    for(int i = 1; i <= 17; i++) {
        int mask = (1 << i);
        for(int j = 1; j <= euler[0] - mask + 1; j ++){
            rmq[i][j] = minn(rmq[i - 1][j], rmq[i - 1][j + (mask >> 1)]);
        }

    }
}

int query(int l, int r)
{
    int length = r - l + 1;
    int mask = lg[length];

    return minn(rmq[mask][l], rmq[mask][r - (1 << mask) + 1]);
}

int main()
{
    fin >> n >> q;
    for(int i = 2; i <= n; i++) {
        fin >> tata[i];
        G[tata[i]].push_back(i);
    }

    lg[1] = 0;
    for(int i = 2; i <= 2e5; i++)
        lg[i] = lg[i >> 1] + 1;

    dfs(1, 0);
    buildRMQ();
    int x, y;
    for(int i = 1; i <= q; i ++)
    {
        fin >> x >> y;
        int L = (timp[x] < timp[y] ? timp[x] : timp[y]);
        int R = (timp[x] > timp[y] ? timp[x] : timp[y]);
        fout << query(L, R) << '\n';
    }

    return 0;
}