Cod sursa(job #3218995)

Utilizator MerlinTheWizardMelvin Abibula MerlinTheWizard Data 29 martie 2024 18:27:04
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.97 kb
#include<bits/stdc++.h>

using namespace std;

const int NMAX = 1e5 + 5, DMAX = 20;
int n, q, dep[NMAX], first[NMAX], tata[NMAX];
vector<int> v[NMAX], lin;
bool viz[NMAX];
pair<int, int> rmq[5 * NMAX][DMAX];

void dfs(int node)
{
    viz[node] = 1;
    lin.push_back(node);
    
    for(auto u : v[node])
    {
        if(!viz[u])
        {
            dep[u] = dep[node] + 1;
            dfs(u);
            lin.push_back(node);
        }
    }
}

int main()
{   
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    freopen("lca.in", "r", stdin);
    freopen("lca.out", "w", stdout);
    cin >> n >> q;
    
    int x, a, b;
    for(int i = 2; i <= n; i++)
    {
        cin >> x;
        v[x].push_back(i);
        v[i].push_back(x);
    }
    
    dep[1] = 1;
    dfs(1);

    
    memset(first, -1, sizeof(first));
    
    for(int i = 0; i < lin.size(); i++)
    {
        if(first[lin[i]] == -1)
            first[lin[i]] = i;
        rmq[i][0].second = lin[i];
        rmq[i][0].first = dep[lin[i]];
    }

    for(int j = 1; j < DMAX; j++)
    {
        for(int i = 0; i < (int)lin.size() - (1 << j); i++)
        {
            rmq[i][j].second = rmq[i][j - 1].second;
            rmq[i][j].first = rmq[i][j - 1].first;
            if(rmq[i][j].first > rmq[i + (1 << (j - 1))][j - 1].first)
            {
                rmq[i][j].first = rmq[i + (1 << (j - 1))][j - 1].first;
                rmq[i][j].second = rmq[i + (1 << (j - 1))][j - 1].second;
            }
        }
    }
        
    for(int i = 1; i <= q; i++)
    {
        cin >> a >> b;
        a = first[a];
        b = first[b];

        if(a > b)
            swap(a, b);

        int p = 0;
        while((1 << (p + 1)) <= (b - a + 1))
            p++;
        if(rmq[a][p].first > rmq[b - (1 << p) + 1][p].first)
            cout << rmq[b - (1 << p) + 1][p].second << "\n";
        else
            cout << rmq[a][p].second << "\n";
    }
}