Cod sursa(job #3224904)

Utilizator TaniaKallosKallos Tania TaniaKallos Data 16 aprilie 2024 15:07:51
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.81 kb
//#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

ifstream cin("lca.in");
ofstream cout("lca.out");


const int N = 1e5, INF = N+1;
int queries, n;
int prima[N+1], ultima[N+1], aint[8*N+1];
vector <int> fii[N+1], tree;


void dfs(int node)
{
    tree.push_back(node);
    for (auto vec : fii[node])
    {
        dfs(vec);
        tree.push_back(node);
    }
}


void build(int node, int l, int r)
{
    if (l == r)
    {
        aint[node] = tree[l];
        return;
    }
    int mid = (l + r)/2;
    build(node*2, l, mid);
    build(node*2+1, mid+1, r);
    aint[node] = min(aint[node*2], aint[node*2+1]);
}

int query(int node, int l, int r, int L, int R)
{
    if (R < l || r < L)
        return INF;
    if (L <= l && r <= R)
        return aint[node];
    int mid = (l + r)/2;
    return min( query(node*2, l, mid, L, R), query(node*2+1, mid+1, r, L, R) );
}


int main()
{
    cin >> n >> queries;

    for (int i = 2; i <= n; i++)
    {
        int daddy;
        cin >> daddy;
        fii[daddy].push_back(i);
    }


    tree.push_back(0); /// umplutura ca sa fie indexat de la 1
    dfs(1);
    int size = tree.size() - 1;

    for (int i = 1; i <= n; i++)
        prima[i] = -1;

    for (int i = 1; i <= size; i++)
    {
        if (prima[ tree[i] ] == -1)
            prima[ tree[i] ] = i;
        ultima[ tree[i] ] = i;
    }

    build(1, 1, size);


    for (int q = 1; q <= queries; q++)
    {
        int x, y;
        cin >> x >> y;

        int st, dr;
        if (prima[x] > prima[y])
            swap(x, y);
        // => prima[x] < prima[y]
        if (prima[y] < ultima[x])
            st = prima[x], dr = prima[y];
        else // prima[x] < ultima[x] < prima[y] < ultima[y]
            st = ultima[x], dr = prima[y];

        cout << query(1, 1, size, st, dr) << '\n';
    }

    return 0;
}