Cod sursa(job #2836627)

Utilizator MihaiZ777MihaiZ MihaiZ777 Data 20 ianuarie 2022 17:49:31
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.78 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <math.h>
using namespace std;

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

int n, m;
vector <int> graph[100005];

struct EulerNode
{
    int node;
    int depth;
};

vector <EulerNode> euler; 
int pos [100005];
int rmq[25][4 * 100005]; // 4 *


void dfs(int node, int depth)
{
    EulerNode newEulerNode = {node, depth};
    euler.push_back(newEulerNode);

    for (int x : graph[node])
    {

        dfs(x, depth + 1);
        euler.push_back(newEulerNode);
    }

    pos[node] = euler.size() - 1;
}

int RMQQuery(int lf, int rg)
{
    int logLen = log2(rg - lf + 1);
    if (euler[rmq[logLen][lf]].depth <= euler[rmq[logLen][rg - (1 << logLen) + 1]].depth)
    {
        return euler[rmq[logLen][lf]].node;
    }
    else
    {
        return euler[rmq[logLen][rg - (1 << logLen) + 1]].node;
    }
}


int main()
{
    fin >> n >> m;
    for (int i = 2; i <= n; i++)
    {
        int x;
        fin >> x;
        graph[x].push_back(i);
    }

    dfs(1, 1);

    for (int i = 0; i < euler.size(); i++)
    {
        rmq[0][i] = i;
    }

    for (int exp = 1; exp < 23; exp++)
    {
        int len = 1 << exp;
        for (int i = 0; i + len - 1 < euler.size(); i++)
        {
            if (euler[rmq[exp - 1][i]].depth <= euler[rmq[exp - 1][(1 << (exp - 1)) + i]].depth)
            {
                rmq[exp][i] = rmq[exp - 1][i];
            }
            else
            {
                rmq[exp][i] = rmq[exp - 1][(1 << (exp - 1)) + i];
            }
        }
    }

    for (int i = 0; i < m; i++)
    {
        int x, y;
        fin >> x >> y;

        fout << RMQQuery(pos[x], pos[y]) << '\n';
    }

    //cout << '\n' << rmq[1][16];


}