Cod sursa(job #2650593)

Utilizator Marius7122FMI Ciltea Marian Marius7122 Data 19 septembrie 2020 14:08:40
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.4 kb
#include <iostream>
#include <fstream>
#include <vector>
 
using namespace std;

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

const int N = 1e5 + 10;
const int LOG = 18;

vector<int> g[N];
int rmq[LOG][2*N], euler[2*N], lvl[N], pos[N], log2[2 * N];
int n, q;

void df(int node, int l)
{
    lvl[node] = l;
    euler[++euler[0]] = node;
    pos[node] = euler[0];
    for(int ch : g[node])
    {
        df(ch, l + 1);
        euler[++euler[0]] = node;
    }
}

int getMin(int x, int y)
{
    if(lvl[x] < lvl[y])
        return x;
    return y;
}

void prep()
{
    df(1, 0);

    log2[1] = 0;
    for(int i = 2; i <= euler[0]; i++)
        log2[i] = log2[i / 2] + 1;

    for(int i = 1; i <= euler[0]; i++)
        rmq[0][i] = euler[i];
    for(int p = 1; (1 << p) <= euler[0]; p++)
        for(int i = 1; i + (1 << p) <= euler[0]; i++)
            rmq[p][i] = getMin(rmq[p-1][i], rmq[p-1][i + (1 << (p - 1))]);
}

int solveQuery(int x, int y)
{
    int px = pos[x];
    int py = pos[y];

    if(px > py)
        swap(px, py);

    int d = py - px + 1;
    int ld = log2[d];
    return getMin(rmq[ld][px], rmq[ld][py - (1 << ld) + 1]);
}

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

    prep();

    while(q--)
    {
        int x, y;
        fin >> x >> y;

        fout << solveQuery(x, y) << '\n';
    }

    return 0;
}