Cod sursa(job #3232205)

Utilizator dariastefLeparda Daria Stefania dariastef Data 29 mai 2024 11:21:33
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.05 kb
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

ifstream fin("lca.in");
ofstream fout("lca.out");

int t[100001];
vector<int> fii[100001];
int n, m, pozInE[100001], E[1700000][2];
int poz, minim[100001][21], minim_pos[100001][21], exp[10001];

void ConstrEuler(int nod, int adancime)
{
    if(pozInE[nod] == 0) pozInE[nod] = poz;
    E[poz][0] = nod;
    E[poz][1] = adancime;
    poz++;
    for(auto y : fii[nod])
    {
        ConstrEuler(y, adancime + 1);
        E[poz][0] = nod;
        E[poz][1] = adancime;
        poz++;
    }
}
void Puteri()
{
    exp[1] = 0;
    for(int i = 2; i <= poz; i++)
        exp[i] = 1 + exp[i / 2];
}
int MinimInterval(int s, int d)
{
    if(s == d)
        return minim[s][0];
    int k = 0;
    while((1<<k)+s <= d) k++;
    k--;
    if((1<<k)+s < d)
        return min(minim[s][k], MinimInterval(s+(1<<k), d));
    else
        return minim[s][k+1];
}

int PozMinim(int s, int d)
{
    int k = 0;
    while((1<<k)+s <= d) k++;
    k--;
    if (s+(1<<k) < d)
        return (minim[s][k] < MinimInterval(s+(1<<k), d) ? minim_pos[s][k] : PozMinim(s+(1<<k), d));
    else
        return minim_pos[s][k+1];
}

int main()
{
    int i, k, interval;
    cin >> n >> m;
    for(i = 2; i <= n; i++)
    {
        cin >> t[i];
        fii[t[i]].push_back(i);
    }

    ConstrEuler(1,0);

    for(i = 0; i < poz; i++)
    {
        minim[i][0] = E[i][1];
        minim_pos[i][0] = i;
    }
    Puteri();
    for(k = 1; k < exp[poz]; k++)
    {
        for(i = 0; i < poz - (1 << (k - 1)); i++)
        {
            minim[i][k] = min(minim[i][k-1], minim[i+(1<<(k-1))][k-1]);
            minim_pos[i][k] = (minim[i][k-1] <= minim[i+(1<<(k-1))][k-1] ? minim_pos[i][k-1] : minim_pos[i+(1<<(k-1))][k-1]);
        }
    }

    for(interval = 1; interval <= m; interval++)
    {
        int x, y;
        cin >> x >> y;
        if (pozInE[x] > pozInE[y]) swap(x, y);
        cout << E[PozMinim(pozInE[x], pozInE[y])][0] << '\n';
    }
    return 0;
}