Cod sursa(job #3003415)

Utilizator TeodoraMaria123Serban Teodora Maria TeodoraMaria123 Data 15 martie 2023 18:38:21
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.65 kb
#include <bits/stdc++.h>

using namespace std;

#define pb push_back
#define MAX_N 100000

const int LOG = 25;

int n, m;
vector <vector <int> > graph;
vector <int> euler, first, height, lg;
pair <int, int> sp[40][2 * MAX_N + 1];
bitset <MAX_N + 1> viz;

void dfs(int node, int h)
{
    viz[node] = 1;
    first[node] = euler.size();
    height[node] = h;
    euler.pb(node);

    for(int neighbour : graph[node])
    {
        if(!viz[neighbour])
        {
            dfs(neighbour, h + 1);
            euler.pb(node);
        }
    }
}

void precalculate()
{
    lg.resize(euler.size() + 1);
    lg[1] = 0;
    for(int i = 2; i <= euler.size(); i ++)
        lg[i] = lg[i / 2] + 1;
}

void sparseTabel()
{
    for(int i = 0; i < euler.size(); i ++)
        sp[0][i].first = height[euler[i]], sp[0][i].second = euler[i];

    for(int i = 1; i <= LOG; i ++)
    {
        int j;
        for(j = 0; j + (1 << i) <= euler.size(); j ++)
        {
            sp[i][j] = min(sp[i - 1][j], sp[i - 1][j + (1 << (i - 1))]);
        }
    }
}

int query(int l, int r)
{
    if(l > r)
        swap(l, r);
    int i = lg[r - l + 1];

//    cout << i << " " << l << " " << r - (1 << i) + 1;
    if(sp[i][l] < sp[i][r - (1 << i) + 1])
        return sp[i][l].second;
    return sp[i][r - (1 << i) + 1].second;
//    return min(sp[i][l], sp[i][r - (1 << i) + 1]);
}

int main()
{
    ios_base :: sync_with_stdio(0);
    cin.tie(0);

    freopen("lca.in", "r", stdin);
    freopen("lca.out", "w", stdout);

    cin >> n >> m;
    graph.resize(n + 1);
    first.resize(n + 1);
    height.resize(n + 1);
    for(int i = 2; i <= n; i ++)
    {
        int x;
        cin >> x;
        graph[x].pb(i);
    }

    dfs(1, 1);
//
//    for(int i = 0; i < euler.size(); i ++)
//        cout << euler[i] << " ";
//    cout << "\n";
//    for(int i = 0; i < euler.size(); i ++)
//        cout << height[euler[i]] << " ";
//    cout << "\n";
//    cout << "\n";
//    for(int x :first)
//        cout << x << " ";

    sparseTabel();
    precalculate();
//    cout << euler.size();

    for(int i = 1; i <= m; i ++)
    {
        int x, y;
        cin >> x >> y;
        cout << query(first[x], first[y]) << "\n";
    }

//    cout << sp[3][11]. first << " " << sp[3][11].second;
//    for(int i = 1; i <= 4; i ++)
//    {
//        for(int j = 0; j < euler.size(); j++)
//            cout << sp[i][j].first << " ";
////            cout << (1 << i) << " " << j << " " << sp[i][j].first << " " << sp[i - 1][j].first<< " " << sp[i - 1][j + (1 << (i - 1))].first<< "\n";
//        cout << "\n";
//    }
    return 0;
}