Cod sursa(job #3291826)

Utilizator mateilucaLuca Matei Gabriel mateiluca Data 5 aprilie 2025 20:13:02
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.53 kb
#include <bits/stdc++.h>

using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
int n, m, poz[100005], L[20], e[200005], k;
pair<int, int> rmq[18][200005];
vector<int> G[100005];
void Euler(int x, int nivel)
{
    rmq[0][++k] = {x, nivel};
    for(int e : G[x])
    {
        Euler(e, nivel + 1);
        rmq[0][++k] = {x, nivel};
    }
}
void LCA()
{
    int i, j;
    Euler(1, 1);
    L[0] = 1;
    for(i = 1;i <= 17;i++)
        L[i] = 2 * L[i - 1];
    e[1] = 0;
    for(i = 2;i <= k;i++)
        e[i] = 1 + e[i / 2];
    for(i = 1;i <= k;i++)
        if(poz[rmq[0][i].first] == 0)
            poz[rmq[0][i].first] = i;
    for(i = 1;i <= e[k];i++)
        for(j = 1;j <= k - L[i] + 1;j++)
            if(rmq[i - 1][j].second <= rmq[i - 1][j + L[i - 1]].second)
                rmq[i][j] = rmq[i - 1][j];
            else rmq[i][j] = rmq[i - 1][j + L[i - 1]];
}

int main()
{
    int i, j, tata, mini, maxi, lung;
    fin >> n >> m;
    for(i = 2;i <= n;i++)
    {
        fin >> tata;
        G[tata].push_back(i);
    }
    LCA();
    for(int ind = 1;ind <= m;ind++)
    {
        fin >> i >> j;
        mini = min(poz[i], poz[j]);
        maxi = max(poz[i], poz[j]);
        lung = L[e[maxi - mini + 1]];
        if(rmq[e[maxi - mini + 1]][mini].second <= rmq[e[maxi - mini + 1]][maxi - lung + 1].second)
            fout << rmq[e[maxi - mini + 1]][mini].first << "\n";
        else fout << rmq[e[maxi - mini + 1]][maxi - lung + 1].first << "\n";
    }
    fout.close();
    return 0;
}