Cod sursa(job #2973354)

Utilizator AlexSerban21Serban Alexandru AlexSerban21 Data 31 ianuarie 2023 20:17:44
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.54 kb
#include <fstream>
#include <vector>
using namespace std;
ifstream fin ("lca.in");
ofstream fout ("lca.out");
vector <int> v[100002];
struct el
{
    int nod,niv;
};
el rmq[18][200002],st,dr;
int sta[100002],p,i,parinte,nrc,x,y,n,q,b[200002];
void liniar (int nod,int nivel)
{
    rmq[0][++nrc]= {nod,nivel};
    sta[nod]=nrc;
    for (int i=0; i<v[nod].size (); i++)
    {
        int vecin=v[nod][i];
        liniar (vecin,nivel+1);
        rmq[0][++nrc]= {nod,nivel};
    }
}
int lca (int x,int y)
{
    int pozx=sta[x];
    int pozy=sta[y];
    if (pozx>pozy)
        swap (pozx,pozy);
    int pp=b[pozy-pozx+1];
    st=rmq[pp][pozx];
    int lg=(1<<pp);
    dr=rmq[pp][pozy-lg+1];
    if (st.niv<dr.niv)
        return st.nod;
    else
        return dr.nod;
}
void minim ()
{
    for (p=1; p<=17; p++)
    {
        for (i=1; i<=nrc; i++)
        {
            int drr=i+(1<<(p-1));
            st=rmq[p-1][i];
            if (drr<=nrc)
            {
                dr=rmq[p-1][drr];
                if (dr.niv<st.niv)
                    rmq[p][i]=dr;
                else
                    rmq[p][i]=st;
            }
            else
                rmq[p][i]=st;
        }
    }
    for (i=2; i<=nrc; i++)
        b[i]=1+b[i/2];
}
int main ()
{
    fin>>n>>q;
    for (i=2; i<=n; i++)
    {
        fin>>parinte;
        v[parinte].push_back (i);
    }
    liniar (1,1);
    minim ();
    for (i=1; i<=q; i++)
    {
        fin>>x>>y;
        fout<<lca (x,y)<<"\n";
    }
    return 0;
}