Cod sursa(job #2982847)

Utilizator gabriel.9619Gabriel Stefan Tita gabriel.9619 Data 20 februarie 2023 23:29:58
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.76 kb
#include <fstream>
#include <vector>
#define dim 100001
#define log 19
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");

struct rmqi{
    int nod, niv;
}rmq[log][2*dim];

int tata[dim], b[2*dim], ps[2*dim];
vector <int> l[dim];
int nr;

void biti()
{
    int i;
    b[1]=0;
    for(i=2;i<=nr;i++)
    {
        b[i]=b[i/2]+1;
    }
}

void dfs(int nod, int niv)
{
    nr++;
    ps[nod]=nr;
    rmq[0][nr]={nod, niv};
    for(int i=0;i<l[nod].size();i++)
    {
        if(tata[nod]!=l[nod][i])
        {
            dfs(l[nod][i], niv+1);
            nr++;
            rmq[0][nr]={nod, niv};
        }
    }
}

void rmq_build()
{
    for(int p=1;p<log;p++)
    {
        for(int nod=1;nod<=nr;nod++)
        {
            rmqi st, dr;
            st=rmq[p-1][nod];
            rmq[p][nod]=st;
            if(nod+(1<<(p-1))<=nr)
            {
                dr=rmq[p-1][nod+(1<<(p-1))];
                if(dr.niv<st.niv)
                {
                    rmq[p][nod]=dr;
                }
            }
        }
    }
}

int lca(int x, int y)
{
    int posx, posy;
    posx=ps[x];
    posy=ps[y];
    if(posx>posy)
    {
        swap(posx, posy);
    }
    int p=b[posy-posx+1];
    rmqi st, dr;
    st=rmq[p][posx];
    dr=rmq[p][posy-(1<<p)+1];
    if(st.niv<dr.niv)
    {
        return st.nod;
    }
    else
    {
        return dr.nod;
    }
}

int main()
{
    int m, n, i, x, y;
    fin>>n>>m;
    for(i=2;i<=n;i++)
    {
        fin>>tata[i];
        l[i].push_back(tata[i]);
        l[tata[i]].push_back(i);
    }
    dfs(1, 0);
    biti();
    rmq_build();
    for(i=1;i<=m;i++)
    {
        fin>>x>>y;
        fout<<lca(x, y)<<"\n";
    }
    return 0;
}