Cod sursa(job #2862700)

Utilizator MenelausSontea Vladimir Menelaus Data 5 martie 2022 18:56:45
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.61 kb
#include <iostream>
#include <fstream>
#include <string.h>
#include <vector>

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

const int N=100000;
const int LOG=17;

std::vector<int> tree[N+1];
int parent[N+1][LOG+1];
int depth[N+1];

void preprocess(int n)
{
    for(int i=1; i<=LOG; i++)
    {
        for(int node=1; node<=n; node++)
        {
            if(parent[node][i-1]!=-1)
            {
                //std::cout<<node<<" "<<i<<"\n";
                parent[node][i]=parent[ parent[node][i-1] ][i-1];
            }
        }
    }
}

int lca(int U, int V)
{
    /// 1. V este cel adanc, U cel sus

    if(depth[V]<depth[U])
    {
        std::swap(V, U);
    }

    /// 2. Aducem V si U la acelasi nivel

    int dif=depth[V]-depth[U];
    for(int i=0; i<=LOG; i++)
    {
        if((dif>>i)&1)
        {
            V=parent[V][i];
        }
    }

    if(U==V)
    {
        return U;
    }

    /// 3. Calculam

    for(int i=LOG; i>=0; i--)
    {
        if(parent[V][i]!=parent[U][i])
        {
          V=parent[V][i];
          U=parent[U][i];
        }
    }

    return parent[V][0];
}

int main()
{
    memset(parent, -1, sizeof(parent));

    int n, m, x, u, v;
    in>>n>>m;

    depth[1]=1;

    for(int i=2; i<=n; i++)
    {
        // x este parintele direct al lui i
        in>>x;

        depth[i]=depth[x]+1;
        parent[i][0]=x;
        tree[x].push_back(i);
    }

    preprocess(n);

    for(int i=1; i<=m; i++)
    {
        in>>u>>v;
        out<<lca(u, v)<<"\n";
    }

    std::cout<<parent[12][1];
}