Cod sursa(job #2922308)

Utilizator tiut_cristianTiut Cristian tiut_cristian Data 7 septembrie 2022 21:54:12
Problema Lowest Common Ancestor Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.21 kb
#include <bits/stdc++.h>

using namespace std;

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

const int MAXN = 100001;
const int LOGMAXN = (int)log2(MAXN);

int n, m, tati[MAXN];
int euler[2*MAXN], k;
int depth[2*MAXN];
int mat[2*MAXN][LOGMAXN];

void citire(int & n, int & m, int tati[])
{
    fin >> n >> m;
    tati[1] = 0;
    for(int i = 2; i <= n; i++)
        fin >> tati[i];
}

void dfs(int node, int crt_depth)
{
    euler[k] = node;
    depth[k++] = crt_depth;
    for(int i = 1; i <= n; i++)
        if(tati[i] == node) {
            dfs(i, crt_depth + 1);
            euler[k] = node;
            depth[k++] = crt_depth;
        }
}

void det_aparitii(int euler[], int k, int n1, int n2, int & st, int & dr)
{
    st = dr = -1;
    int gasit = 0;
    for(int i = 0; i < k && gasit < 2; i++)
    {
        if(euler[i] == n1)
        {
            if(st == -1)
                st = i, gasit++;
        }
        else if(euler[i] == n2)
        {
            if(dr == -1)
                dr = i, gasit++;
        }
    }
}

void generare_matrice(int M[][LOGMAXN], int A[], int N)
{
    for (int i = 0; i < N; i++)
        M[i][0] = i;
    //M[i][j] is the index of the minimum value in the sub array starting at i having length 2^j
    for (int j = 1; (1 << j) <= N; j++)
    {
        const int cN = N - (1 << j);
        for (int i = 0; i <= cN; i++)
            if (A[ M[i][j - 1] ] < A[ M[i + (1 << (j - 1))][j - 1] ])
                M[i][j] = M[i][j - 1];
            else
                M[i][j] = M[i + (1 << (j - 1))][j - 1];
    }
}

int main()
{
    citire(n, m, tati);
    dfs(1, 0);
    generare_matrice(mat, depth, k);

    for(int i = 1; i <= m; i++)
    {
        int st, dr;
        fin >> st >> dr;

        int ist, idr;
        det_aparitii(euler, k, st, dr, ist, idr);
        if(ist > idr)
            swap(ist, idr);

        int maxpower = (int)log2(idr-ist+1);
        if(depth[ mat[ist][maxpower] ] < depth[ mat[idr + 1 - (1 << maxpower)][maxpower] ])
            fout << euler[ mat[ist][maxpower] ] << '\n';
        else
            fout << euler[ mat[idr + 1 - (1 << maxpower)][maxpower] ] << '\n';
    }

    return 0;
}