Cod sursa(job #2509674)

Utilizator Briana_NeaguNeagu Briana Briana_Neagu Data 14 decembrie 2019 15:23:00
Problema Lowest Common Ancestor Scor 30
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.37 kb
#include <bits/stdc++.h>

using namespace std;

//varianta 3 - Euler + Rmq

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

const int nmax = 100005;

vector <int> son[nmax];
vector <int> euler;

int level[nmax];
int first[nmax];
int dp[nmax * 2][15];

void dfs(int nod, int lvl)
{
    euler.push_back(nod);
    level[nod] = lvl;
    first[nod] = (int) euler.size() - 1;
    dp[euler.size() - 1][0] = nod;
    for (auto el : son[nod])
    {
        dfs(el, lvl + 1);
        euler.push_back(nod);
        dp[euler.size() - 1][0] = nod;
    }
}

int main()
{
    int n, m;
    f >> n >> m;
    for (int i = 1; i < n; ++ i)
    {
        int x;
        f >> x;
        son[x].push_back(i + 1);
    }

    dfs(1, 1);
    for (int j = 1; (1 << j) < euler.size(); ++ j)
        for (int i = 0; i + (1 << j) <= euler.size(); ++ i)
            if (level[dp[i][j - 1]] < level[dp[i + (1 << (j - 1))][j - 1]])
                dp[i][j] = dp[i][j -1];
            else
                dp[i][j] = dp[i + (1 << (j - 1))][j - 1];

    for (int i = 1; i <= m; ++ i)
    {
        int a, b;
        f >> a >> b;
        a = first[a];
        b = first[b];
        if (a > b)
            swap(a, b);
        int d = b - a + 1;
        int l = (int)log2(d);
        if (level[dp[a][l]] < level[dp[a + d - (1 << l)][l]])
            g << dp[a][l];
        else
            g << dp[a + d - (1 << l)][l];
        g << '\n';
    }
}