Cod sursa(job #3216747)

Utilizator hhhhhhhAndrei Boaca hhhhhhh Data 19 martie 2024 17:05:01
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.72 kb
#include <bits/stdc++.h>

using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
int n,q,par[100005],in[100005],out[100005],lin[500005],rmq[21][500005],timp,niv[100005],loga[500005];
vector<int> muchii[100005];
void dfs(int nod)
{
    timp++;
    lin[timp]=nod;
    in[nod]=timp;
    bool have=0;
    for(int i:muchii[nod])
    {
        niv[i]=niv[nod]+1;
        dfs(i);
        have=1;
        timp++;
        lin[timp]=nod;
    }
    if(!have)
    {
        timp++;
        lin[timp]=nod;
    }
    out[nod]=timp;
}
bool isancestor(int a,int b)
{
    return in[a]<=in[b]&&out[a]>=out[b];
}
int getmin(int l,int r)
{
    int lg=loga[r-l+1];
    int a=rmq[lg][r-(1<<lg)+1];
    int b=rmq[lg][l];
    if(niv[a]<niv[b])
        return a;
    return b;
}
int LCA(int a,int b)
{
    if(in[a]>in[b])
        swap(a,b);
    if(isancestor(a,b))
        return a;
    int l=out[a];
    int r=in[b];
    return getmin(l,r);
}
int main()
{
    ios_base::sync_with_stdio(false);
    fin.tie(0);
    fin>>n>>q;
    for(int i=2;i<=n;i++)
    {
        fin>>par[i];
        muchii[par[i]].push_back(i);
    }
    dfs(1);
    for(int i=1;i<=timp;i++)
    {
        for(int bit=0;bit<=20;bit++)
            if((1<<bit)<=i)
                loga[i]=bit;
    }
    for(int i=1;i<=timp;i++)
        rmq[0][i]=lin[i];
    for(int j=1;j<=20;j++)
        for(int i=1;i<=timp;i++)
        {
            rmq[j][i]=rmq[j-1][i];
            int poz=i+(1<<(j-1));
            if(poz<=timp&&niv[rmq[j-1][poz]]<niv[rmq[j][i]])
                rmq[j][i]=rmq[j-1][poz];
        }
    while(q--)
    {
        int a,b;
        fin>>a>>b;
        fout<<LCA(a,b)<<'\n';
    }
    return 0;
}