Cod sursa(job #3152644)

Utilizator Samoila_AlexandruSamoilaAlexandru Samoila_Alexandru Data 26 septembrie 2023 00:01:10
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.27 kb
#include <fstream>
#include <vector>

using namespace std;

ifstream fin("lca.in");
ofstream fout("lca.out");

const int nMax=(int)1e5 + 5, lognMax=16;

int n, q, u, v, t[lognMax][nMax], timpIntrare[nMax], timpIesire[nMax], timp;
vector<int> g[nMax];

bool isAncestor(int u, int v)
{
    return (timpIntrare[u]<=timpIntrare[v] && timpIesire[v]<=timpIesire[u]);
}

void build()
{
    for(int i=1; (1<<i)<=n; i++)
        for(int j=1; j<=n; j++)
        t[i][j]=t[i-1][t[i-1][j]];
}

void dfs(int k)
{
    timpIntrare[k]=++timp;
    for(auto i: g[k])
        if(timpIntrare[i]==0)
    {
        t[0][i]=k;
        dfs(i);
    }

    timpIesire[k]=++timp;
}

int lca(int u, int v)
{
    if(isAncestor(u, v))
        return u;

    int p=lognMax;
    while(p>=0)
    {
        if(t[p][u] && !isAncestor(t[p][u], v))
            u=t[p][u];

        p--;
    }

    return t[0][u];
}

int main()
{
    ios_base::sync_with_stdio(false);
    fin.tie(0);

    fin>>n>>q;
    for(int i=2; i<=n; i++)
    {
        fin>>t[0][i];
        g[t[0][i]].push_back(i);
    }

    dfs(1);
    build();

    for(int i=0; i<q; i++)
    {
        fin>>u>>v;
        fout<<lca(u, v)<<'\n';
    }

    fin.close();
    fout.close();
    return 0;
}