Cod sursa(job #2398226)

Utilizator MaxTeoTeo Oprescu MaxTeo Data 5 aprilie 2019 10:46:43
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.88 kb
#include <bits/stdc++.h>
#define N 100005
#define LOGN 20
#define INF 0x3f3f3f3f
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");

struct element
{
    int nod, level;
};

int rmq[3 * N][LOGN], n, m, a, b, first[N];
vector<int> graph[N];
vector<element> euler;

void dfs(int nod, int level)
{
    if(!first[nod])
        first[nod] = euler.size();
    euler.push_back({nod, level});
    for(auto next : graph[nod])
    {
        dfs(next, level + 1);
        euler.push_back({nod, level});
    }
}

void createEuler()
{
    dfs(1, 1);
}

void Print()
{
    for(int i = 0; i < euler.size(); ++i)
        g << i << " ";
    g << '\n';
    for(auto i : euler)
        g << i.nod << " ";
    g << '\n';
    for(auto i : euler)
        g << i.level <<" ";
    g << '\n';
}

void generateRMQ()
{
    for(int i = 0; i < euler.size(); ++i)
        rmq[i][0] = i;
    for(int j = 1; (1 << j) < euler.size(); ++j)
        for(int i = 0; i + (1 << (j - 1)) < euler.size(); ++i)
        {
            int dif = i + (1 << (j - 1));
            if(euler[rmq[i][j - 1]].level < euler[rmq[dif][j - 1]].level)
                rmq[i][j]=rmq[i][j - 1];
            else
                rmq[i][j]=rmq[dif][j - 1];
        }
}

void Solve(int a, int b)
{
    int i1 = first[a], i2 = first[b];
    if(i1 > i2)
        swap(i1, i2);
    int log = log2(i2 - i1 + 1), ans=0;
    int x1 = rmq[i1][log];
    int x2 = rmq[i2 - (1 << log) +1][log];
    if(euler[x1].level < euler[x2].level)
        g<<euler[x1].nod;
    else
        g<<euler[x2].nod;
    g<<'\n';
}

int main()
{
    f >> n >> m;
    for(int i=2;i<=n;++i)
    {
        f >> a;
        graph[a].push_back(i);
    }
    euler.push_back({0, INF});
    createEuler();
    generateRMQ();
    while(m--)
    {
        f >> a >> b;
        Solve(a, b);
    }
    return 0;
}