Cod sursa(job #3226040)

Utilizator adelinapetreAdelina Petre adelinapetre Data 19 aprilie 2024 19:00:23
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.81 kb
#include <fstream>
#include <vector>
using namespace std;
ifstream cin ("lca.in");
ofstream cout ("lca.out");
int tata[100005], aint[800005], nivel[100005], ap[100005];
vector<int> euler;
vector<int>fii[100005];
void update(int nod, int st, int dr, int poz, int val)
{
    if(st > poz || dr < poz)
        return;
    if(st == dr && dr == poz)
    {
        aint[nod] = val;
        return;
    }
    update(nod * 2, st, (st + dr) / 2, poz, val);
    update(nod * 2 + 1, (st + dr) / 2 + 1, dr, poz, val);
    if(nivel[aint[nod * 2]] < nivel[aint[nod * 2 + 1]])
        aint[nod] = aint[nod * 2];
    else
        aint[nod] = aint[nod * 2 + 1];
}
int query(int nod, int st, int dr, int x, int y)
{
    if(y < st || x > dr)
        return 0;
    if(x <= st && dr <= y)
        return aint[nod];
    int a = query(nod * 2, st, (st + dr) / 2, x, y);
    int b = query(nod * 2 + 1, (st + dr) / 2 + 1, dr, x, y);
    if(nivel[a] < nivel[b])
        return a;
    return b;
}
void dfs(int nod)
{
    euler.push_back(nod);
    if(nod != 1)
        nivel[nod] = nivel[tata[nod]] + 1;
    else
        nivel[nod] = 1;
    for(auto it : fii[nod])
    {
        dfs(it);
        euler.push_back(nod);
    }
}
int main()
{
    int n, m, i, x, y;
    cin >> n >> m;
    for(i = 2; i <= n; i ++)
    {
        cin >> tata[i];
        if(tata[i] != i)
            fii[tata[i]].push_back(i);
    }
    nivel[0] = 21e8;
    dfs(1);
    for(i = 0; i < euler.size(); i ++)
        update(1, 1, euler.size(), i + 1, euler[i]);
    for(i = 0; i < euler.size(); i ++)
        if(ap[euler[i]] == 0)
            ap[euler[i]] = i + 1;
    for(i = 1; i <= m; i ++)
    {
        cin >> x >> y;
        cout << query(1, 1, euler.size(), min(ap[x], ap[y]), max(ap[x], ap[y]))  << '\n';
    }
    return 0;
}