Cod sursa(job #2549583)

Utilizator FrostfireMagirescu Tudor Frostfire Data 17 februarie 2020 20:12:31
Problema Lowest Common Ancestor Scor 0
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, log2[5*NMAX+10], rmq[5*NMAX+10][25], fa[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 cmp(int poz1, int poz2)
{   if(euler[poz1].second <= euler[poz2].second) return poz1;
    return poz2;
}

void init()
{   log2[1] = 0;
    for(int i=2; i<=5*NMAX+10; i++)
        {   log2[i] = log2[i-1];
            if((i & (i-1)) == 0) log2[i]++;
        }
    for(int i=0; i<euler.size(); i++) rmq[i][0] = i;
    for(int i=1; (1<<i)<=euler.size(); i++)
        for(int j=0; j<=euler.size()-(1<<i); j++)
            rmq[j][i] = cmp(rmq[j][i-1], rmq[j+(1<<(i-1))][i-1]);
}

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