Cod sursa(job #2734096)

Utilizator Tudor_PascaTudor Pasca Tudor_Pasca Data 31 martie 2021 13:09:13
Problema Lowest Common Ancestor Scor 40
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.9 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <cstring>

using namespace std;

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

const int INF = 0x3f3f3f3f3f3f3f3f3f;

int n, q, e;
int log[200100], rmq[200100][23], first[100100];
bool fr[100100];
vector<int> euler;
vector<vector<int>> adj;

void eulerDfs(int node)
{
    fr[node] = 1;
    euler.push_back(node);
    first[node] = min(first[node], (int)euler.size() - 1);

    for(auto it: adj[node])
    {
        if(!fr[it])
        {
            eulerDfs(it);
            euler.push_back(node);
        }
    }
}

void precalc()
{
    for(int i = 2; i <= e; i++)
        log[i] = log[i / 2] + 1;

    for(int i = 0; i < e; i++)
        rmq[i][0] = euler[i];

    for(int j = 1; j <= log[e]; j++)
        for(int i = 0; i + (1 << log[j]) - 1 < e; i++)
            rmq[i][j] = min(rmq[i][j - 1], rmq[i + (1 << (j - 1))][j - 1]);
}

int lca(int x, int y)
{
    x = first[x];
    y = first[y];

    if(x > y)
        swap(x, y);

    int len = y - x + 1;

    //cout << x << ' ' << y << ' ' << log[len] << '\n';

    return min(rmq[x][log[len]], rmq[y - (1 << log[len]) + 1][log[len]]);
}

int main()
{
    memset(first, INF, sizeof first);

    in >> n >> q;

    adj.resize(n + 5);

    for(int i = 2; i <= n; i++)
    {
        int x;
        in >> x;

        adj[x].push_back(i);
    }

    eulerDfs(1);

    e = euler.size();

    precalc();

    /*
    for(int i = 0; i < e; i++)
        cout << euler[i] << ' ';

    cout << '\n';

    for(int i = 0; i < e; i++)
    {
        cout << "i: " << i << '\n';
        for(int j = 0; i + (1 << j) - 1 < e; j++)
            cout << j << ' ' << rmq[i][j] << '\n';
        cout << '\n';
    }
    */

    while(q--)
    {
        int x, y;
        in >> x >> y;

        out << lca(x, y) << '\n';
    }

    return 0;
}