Cod sursa(job #2602345)

Utilizator Chirac_MateiChiriac Matei Chirac_Matei Data 16 aprilie 2020 18:41:24
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.55 kb
#include <bits/stdc++.h>

using namespace std;
ifstream fin ("lca.in");
ofstream fout ("lca.out");
struct nodS
{
    int par,d,f;
    vector <int> cop;
};
int n,m,i,x,y;
int rmq[200005][40];
nodS nod[100005];
vector <int> euler;
void dfs(int poz)
{
    nod[poz].d=nod[nod[poz].par].d+1;
    euler.push_back(poz);
    nod[poz].f=euler.size()-1;

    for(int it : nod[poz].cop)
    {
        dfs(it);
        euler.push_back(poz);
    }
}
void build_rmq()
{
    int n=euler.size();
    for(int b=0;(1<<b)<n;b++)
    {
        for(int i=0;i+(1<<b)-1<n;i++)
        {
            if(b==0)
                rmq[i][b]=euler[i];
            else
            {
                int ansl, ansr;
                ansl=rmq[i][b-1];
                ansr=rmq[i+(1<<b)/2][b-1];

                if(nod[ansl].d<nod[ansr].d)
                    rmq[i][b]=ansl;
                else
                    rmq[i][b]=ansr;
            }
        }
    }
}
int query(int l, int r)
{
    int ansl, ansr;
    int b=0;

    while(2*(1<<b)<r-l+1)
        b++;

    ansl=rmq[l][b];
    ansr=rmq[r-(1<<b)+1][b];

    if(nod[ansl].d<nod[ansr].d)
        return ansl;
    else
        return ansr;
}
int main()
{
    fin>>n>>m;
    for(i=2;i<=n;i++)
    {
        fin>>x;
        nod[i].par=x;
        nod[x].cop.push_back(i);
    }

    dfs(1);
    build_rmq();

    for(i=1;i<=m;i++)
    {
        fin>>x>>y;

        if(nod[x].f>nod[y].f)
            swap(x,y);

        fout<<query(nod[x].f, nod[y].f)<<'\n';
    }
    return 0;
}