Cod sursa(job #3174333)

Utilizator alexandru.morusAlexandru Morus alexandru.morus Data 24 noiembrie 2023 17:38:08
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.14 kb
///Alexandru Morus
#include <bits/stdc++.h>
using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
int v[100006],vf[100006],cnt = 0,primul[100006];
pair <int,int> aint[500006];
vector<int> g[100006];
int mt[100006][3],af,afs;
void dfs(int nod, int nivel)
{
    vf[nod] = 1;
    for(auto i : g[nod])
    {
        if(vf[i] == 0)
        {
            cnt ++;
            mt[cnt][1] = nod;
            mt[cnt][2] = nivel;
            if(primul[nod] == 0)
            {
                primul[nod] = cnt;
            }
            dfs(i,nivel + 1);
        }
    }
    cnt ++;
    mt[cnt][1] = nod;
    mt[cnt][2] = nivel;
    if(primul[nod] == 0)
    {
        primul[nod] = cnt;
    }
}
void build(int node, int left, int right)
{
    if(left == right)
    {
        aint[node].first = mt[left][2];
        aint[node].second = mt[left][1];
        return;
    }
    int mid = (left + right) / 2;
    build(2 * node,left,mid);
    build(2 * node + 1, mid + 1, right);
    if(aint[2 * node].first < aint[2 * node + 1].first)
    {
        aint[node].first = aint[2 * node].first;
        aint[node].second = aint[2 * node].second;
    }
    else
    {
        aint[node].first = aint[2 * node + 1].first;
        aint[node].second = aint[2 * node + 1].second;
    }
}
void query(int node, int left, int right, int a, int b)
{
    if(a <= left && right <= b)
    {
        if(aint[node].first < af)
        {
            af = aint[node].first;
            afs = aint[node].second;
        }
        return;
    }
    long long mid = (left + right) / 2;
    if(a <= mid)
    {
        query(2 * node, left, mid,a,b);
    }
    if(b > mid)
    {
        query(2 * node + 1, mid + 1, right,a,b);
    }
}
int main()
{
    int n,i,a,b,m;
    in >> n >> m;
    for(i = 1; i < n; i ++)
    {
        in >> v[i];
        g[v[i]].push_back(i + 1);
        g[i + 1].push_back(v[i]);
    }
    dfs(1,1);
    build(1,1,cnt);
    for(i = 1; i <= m; i ++)
    {
        af = 99999999;
        in >> a >> b;
        query(1,1,cnt,primul[a],primul[b]);
        out << afs << '\n';
    }
    return 0;
}