Cod sursa(job #3186162)

Utilizator Theo20067Cismaru Theodor-Alexe Theo20067 Data 21 decembrie 2023 20:12:36
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.44 kb
#include <fstream>
#include <vector>
using namespace std;
ifstream fin ("lca.in");
ofstream fout("lca.out");
int n,m,i,k,x,y,j,l,t,P[200005],start[200005];
vector <int> V[100005];
struct RMQ
{
    int nod,niv;
}D[19][200005];
void dfs(int nod, int niv)
{
    D[0][++k]={nod,niv};
    start[nod]=k;
    for(int j=0;j<V[nod].size();j++)
    {
        int fiu=V[nod][j];
        dfs(fiu,niv+1);
        D[0][++k]={nod,niv};
    }
}
void rmq()
{
    for(int p=1;p<19;p++)
    {
        for(int i=1;i<=k;i++)
        {
            RMQ st=D[p-1][i];
            D[p][i]=st;
            if(i+(1<<(p-1))<=k)
            {
                RMQ dr=D[p-1][i+(1<<(p-1))];
                if(st.niv<dr.niv)
                    D[p][i]=st;
                else
                    D[p][i]=dr;
            }

        }
    }
    P[1]=0;
    for(int i=2;i<=k;i++)
        P[i]=P[i/2]+1;

}
int lca(int x,int y)
{
    int pos_x=start[x];
    int pos_y=start[y];
    if(pos_x>pos_y)
        swap(pos_x,pos_y);
    int p=P[pos_y-pos_x+1];
    RMQ st=D[p][pos_x];
    RMQ dr=D[p][pos_y-(1<<p)+1];
    if(st.niv<dr.niv)
        return st.nod;
    else
        return dr.nod;
}
int main()
{
    fin>>n>>m;
    for(i=2;i<=n;i++)
    {
        fin>>x;
        V[x].push_back(i);
    }
    k=0;
    dfs(1,1);
    rmq();
    for(i=1;i<=m;i++)
    {
        fin>>x>>y;
        fout<<lca(x,y)<<"\n";
    }
    return 0;
}