Cod sursa(job #3265767)

Utilizator maryyMaria Ciutea maryy Data 3 ianuarie 2025 02:14:53
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.6 kb
#include<bits/stdc++.h>

using namespace std;

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

const int NMAX=100001, LGMAX=20;
int n, m, x, y;
int lvl[NMAX], ancestor[LGMAX][NMAX];//al 2^i lea  stramos al lui j
vector <int> graph[NMAX];

void dfsLevels(int node)
{
    for(int next:graph[node])
    {
        lvl[next]=lvl[node]+1;
        dfsLevels(next);
    }
}

void binary_lifting()
{
    for(int i=1; i<LGMAX; i++)
        for(int j=1; j<=n; j++)
            ancestor[i][j] = ancestor[i-1][ancestor[i-1][j]];
}

int XThAncestor(int node, int x)
{
    if(x >= (1<<LGMAX))
        return 0;
    for(int i=0; i<LGMAX; i++)
    {
        if( x&(1<<i) )//bitul i din x este setat -> sar cu 2^i
            node=ancestor[i][node];
    }
    return node;
}

int lca(int node1,int node2)
{
    if(lvl[node1]<lvl[node2])
        swap(node1,node2);

    node1=XThAncestor(node1, lvl[node1]-lvl[node2] );//ridic nodul 1 la nivelul celuilalt
    if(node1==node2)
        return node1;

    for(int i=LGMAX-1; i>=0; i--)
        if(ancestor[i][node1]!=ancestor[i][node2])//al 2^i lea ancestor nu e comun -> sar cu cate 2^i la fiecare
        {
            node1 = ancestor[i][node1];
            node2 = ancestor[i][node2];
        }
    return ancestor[0][node1];
}

int main()
{
    in>>n>>m;
    for(int i=2; i<=n; i++)
    {
        in>>ancestor[0][i];//tatal nodului i
        graph[ ancestor[0][i] ].push_back(i);
    }
    dfsLevels(1);
    binary_lifting();
    for(int i=1; i<=m; i++)
    {
        in>>x>>y;
        out<<lca(x,y)<<'\n';
    }
    return 0;
}