Cod sursa(job #1921572)

Utilizator dorin31Geman Dorin Andrei dorin31 Data 10 martie 2017 13:17:28
Problema Paduri de multimi disjuncte Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.3 kb
#include <iostream>
#include <fstream>
#include <vector>

#define maxN 100010

using namespace std;

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

int n,m,nr_rmq,rmq[20][2*maxN],first[maxN],lvl[maxN];
vector <int> v[maxN];

void readData()
{
    fin>>n>>m;
    for (int i=2; i<=n; ++i)
    {
        int x;
        fin>>x;
        v[x].push_back(i);
    }
}

void DFS(int x)
{
    rmq[0][++nr_rmq]=x;
    first[x]=nr_rmq;
    for (auto it:v[x])
    {
        lvl[it]=lvl[x]+1;
        DFS(it);
        rmq[0][++nr_rmq]=x;
    }
}

void makeRMQ()
{
    for (int l = 1; (1 << l) <= nr_rmq; ++l)
		for (int st = 1; st + (1 << l) <= nr_rmq; ++st) {
			int dr = st + (1 << (l - 1));
			if (lvl[rmq[l - 1][st]] < lvl[rmq[l - 1][dr]])
				rmq[l][st] = rmq[l - 1][st];
			else
				rmq[l][st] = rmq[l - 1][dr];
		}
}

int LCA(int a, int b)
{
    a=first[a];
    b=first[b];
    if (a>b) swap(a,b);
    else if (a==b) return a;
    int d = 0;
	while ((1 << d) < (b - a + 1))
		++d;
	--d;
	if (lvl[rmq[d][a]] < lvl[rmq[d][b - (1 << d) + 1]])
		return rmq[d][a];
	return rmq[d][b - (1 << d) + 1];
}

int main()
{
    readData();
    DFS(1);
    makeRMQ();
    while (m--)
    {
        int x,y;
        fin>>x>>y;
        fout<<LCA(x,y)<<'\n';
    }
    return 0;
}