Cod sursa(job #3193949)

Utilizator Giulian617Buzatu Giulian Giulian617 Data 16 ianuarie 2024 10:59:22
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.59 kb
#include<bits/stdc++.h>
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");
const int NMAX=100005,LOGMAX=20;
int n,m,x,y,level[NMAX],ancestor[LOGMAX][NMAX];
/// ancestor[i][j] = the 2^i ancestor of j
vector<int>graph[NMAX];
void dfs(int node)
{
    for(int next:graph[node])
    {
        level[next]=level[node]+1;
        dfs(next);
    }
}
void binary_lifting()
{
    for(int i=1; i<LOGMAX; i++)
        for(int j=1; j<=n; j++)
            ancestor[i][j]=ancestor[i-1][ancestor[i-1][j]];
}
int find_ancestor(int node,int no_ancestor)
{
    if(no_ancestor>=(1<<LOGMAX))
        return 0;
    for(int i=0; i<LOGMAX; i++)
        if(no_ancestor&(1<<i))
            node=ancestor[i][node];
    return node;
}
int lca(int node1,int node2)
{
    if(level[node1]<level[node2])
        swap(node1,node2);

    node1=find_ancestor(node1,level[node1]-level[node2]);/// bring the nodes to the same level
    if(node1==node2)
        return node1;/// node2 is the lca

    /// finding the lca otherwise
    for(int i=LOGMAX-1; i>=0; i--)
        if(ancestor[i][node1]!=ancestor[i][node2])
        {
            node1=ancestor[i][node1];
            node2=ancestor[i][node2];
        }
    return ancestor[0][node1];/// because node1 and node2 are right under LCA
}
int main()
{
    f>>n>>m;
    for(int i=2; i<=n; i++)
    {
        f>>ancestor[0][i];
        graph[ancestor[0][i]].push_back(i);
    }
    level[1]=0;
    dfs(1);
    binary_lifting();
    for(int i=1; i<=m; i++)
    {
        f>>x>>y;
        g<<lca(x,y)<<'\n';
    }
    return 0;
}