Cod sursa(job #2548380)

Utilizator FrostfireMagirescu Tudor Frostfire Data 16 februarie 2020 16:30:27
Problema Lowest Common Ancestor Scor 30
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.44 kb
#include <iostream>
#include <fstream>
#include <vector>
#define NMAX 100000

using namespace std;

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

int n, q, m, rmq[NMAX+10][20], fa[NMAX+10], log2[NMAX+10];
vector <int> nod[NMAX+10];
vector <pair <int, int> > euler;

void dfs(int x, int l)
{   euler.push_back(make_pair(x, l));
    fa[x] = euler.size() - 1;
    for(int i=0; i<nod[x].size(); i++)
        dfs(nod[x][i], l+1), euler.push_back(make_pair(x, l));
}

int minim(int val1, int val2)
{   if(euler[val1].second <= euler[val2].second) return val1;
    return val2;
}

void init()
{   log2[1] = 0;
    for(int i=2; i<=NMAX; i++)
        {   log2[i] = log2[i-1];
            if((i & (i-1)) == 0) log2[i]++;
        }
    for(int i=0; i<m; i++) rmq[i][0] = i;
    for(int i=1; (1<<i)<=m; i++)
        for(int j=0; j<=m-(1<<i); j++)
            rmq[j][i] = minim(rmq[j][i-1], rmq[j+(1<<(i-1))][i-1]);
}

int main()
{
    f >> n >> q;
    for(int i=2; i<=n; i++)
        {   int nod1, nod2 = i;
            f >> nod1;
            nod[nod1].push_back(nod2);
        }
    dfs(1, 0);
    m = euler.size();
    init();
    while(q--)
        {   int x, y;
            f >> x >> y;
            if(fa[x] > fa[y]) swap(x, y);
            x = fa[x];
            y = fa[y];
            int put = log2[y-x+1];
            g << euler[minim(rmq[x][put], rmq[y-(1<<put)+1][put])].first << '\n';
        }
    return 0;
}