Cod sursa(job #3199390)

Utilizator NiffSniffCojocaru Calin Marcu NiffSniff Data 1 februarie 2024 16:06:50
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.56 kb
#include <fstream>
#include <vector>
using namespace std;
string file = "lca";
ifstream cin (file + ".in");
ofstream cout (file + ".out");
const int N = 200000, LOG = 16;
vector <int> L[N];
int prima_ap[2*N+1], e[2*N+1], n_e, rmq[LOG+1][2*N+1], nivel[N+1], log2[2*N+1];
void dfs(int x, int l = 0)
{

    e[++n_e] = x;
    prima_ap[x] = n_e;
    nivel[x] = l;
    for (int y : L[x])
    {
        dfs(y,l+1);
        e[++n_e] = x;
    }
}

void constructie_rmq()
{
    for (int j=1; j<=n_e; j++)
    {
        rmq[0][j] = e[j];
    }
    for (int i=1; (1<<i) <= n_e; i++)
    {
        for (int j=(1<<i); j<=n_e; j++)
        {
            int p = (1<<(i-1));
            rmq[i][j] = rmq[i-1][j-p];
            if (nivel[rmq[i-1][j]] < nivel[rmq[i][j]])
                rmq[i][j] = rmq[i-1][j];
            //cout << rmq[i][j] << ' ';
        }
    }
    log2[1] = 0;
    for (int i=2; i<=n_e; i++)
    {
        log2[i] = 1 + log2[i/2];
    }
}

int interogare (int st, int dr)
{
    if (st > dr)
    {
        swap(st,dr);
    }
    int lung = dr-st+1, p = log2[lung], rezultat;
    rezultat = rmq[p][st+(1<<p)-1];
    if (nivel[rmq[p][dr]] < nivel[rezultat])
    {
        rezultat = rmq[p][dr];
    }
    return rezultat;
}
int main()
{
    int n,m,x,y;
    cin >> n >> m;
    for (int i=2; i<=n; i++)
    {
        cin >> x;
        L[x].push_back(i);
    }
    dfs(1);
    constructie_rmq();
    for (int i=1; i<=m; i++)
    {
        cin >> x >> y;
        cout << interogare(prima_ap[x],prima_ap[y]) << '\n';
    }
}