Cod sursa(job #3218993)

Utilizator MerlinTheWizardMelvin Abibula MerlinTheWizard Data 29 martie 2024 18:15:17
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.93 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()
{   
    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; (1 << j) < lin.size(); 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;
         if(first[a] > first[b])
            swap(a, b);
        int p = 0;
        while((1 << (p + 1)) <= (first[b] - first[a] - 1))
            p++;
        if(rmq[first[a] + 1][p].first > rmq[first[b] - (1 << p)][p].first)
            cout << rmq[first[b] - (1 << p)][p].second << "\n";
        else
            cout << rmq[first[a] + 1][p].second << "\n";
    }
}