Cod sursa(job #2733302)

Utilizator emanuel2186Lugojan Emanuel emanuel2186 Data 30 martie 2021 11:05:55
Problema Lowest Common Ancestor Scor 40
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.34 kb
#include <bits/stdc++.h>
#define Nmax 100005
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
vector<int> fii[Nmax];
int N, M;
bool frec[Nmax];
vector<pair<int, int> > euler;
int poz[Nmax];
struct punct
{
    int nod, nivel;
};
punct arb[Nmax * 4];
void build(int k, int left, int right)
{
    if(left == right)
    {
        arb[k].nivel = euler[left - 1].second;
        arb[k].nod = euler[left - 1].first;
        return;
    }
    int mid = (left + right) / 2;
    build(2 * k, left, mid);
    build(2 * k + 1, mid + 1, right);
    if(arb[2 * k + 1].nivel >= arb[2 * k].nivel)
    {
        ///fiul din stanga e mai bun
        arb[k].nivel = arb[2 * k].nivel;
        arb[k].nod = arb[2 * k].nod;
    }
    else
    {
        arb[k].nivel = arb[2 * k + 1].nivel;
        arb[k].nod = arb[2 * k + 1].nod;
    }
}
int minim = INT_MAX;
int rez = -1;
void query(int k, int left, int right, int Qleft, int Qright)
{
    if(Qleft <= left && Qright >= right)
    {
        if(arb[k].nivel < minim)
        {
            minim = arb[k].nivel;
            rez = arb[k].nod;
        }
        return;
    }
    if(Qleft > right || Qright < left)
        return;
    int mid = (left + right) / 2;
    query(2 * k, left, mid, Qleft, Qright);
    query(2 * k + 1, mid + 1, right, Qleft, Qright);

}
int dfs(int nod, int k)
{
    frec[nod] = 1;
    int fiu;
    euler.push_back(make_pair(nod, k));
    poz[nod] = euler.size();
    for(int j=0; j<fii[nod].size(); j++)
    {
        fiu = fii[nod][j];
        if(frec[fiu] == 0)
        {

            dfs(fiu, k + 1);
            euler.push_back(make_pair(nod, k));
        }
    }
}
void afisare()
{
    for(int i=0; i<euler.size(); i++)
    {
        //cout<<euler[i].first<<" "<<euler[i].second<<"\n"<<"\n";
    }

}
void citire()
{
    fin>>N>>M;
    int tata, a, b;
    for(int i=2; i<=N; i++)
    {
        fin>>tata;
        fii[tata].push_back(i);
    }
    dfs(1, 0);
    int d = euler.size();
    build(1, 1, d);
    for(int i=1; i<=M; i++)
    {
        fin>>a>>b;
        a = poz[a];
        b = poz[b];
        if(a > b)
            swap(a, b);
        minim = INT_MAX;
        rez = -1;
        query(1, 1, d, a, b);
        fout<<rez<<"\n";
    }
}
int main()
{
    citire();
    afisare();
    return 0;
}