Cod sursa(job #1502280)

Utilizator cosmin.pascaruPascaru Cosmin cosmin.pascaru Data 14 octombrie 2015 15:24:23
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.43 kb
#include <fstream>
#include <bitset>
#include <vector>
#include <utility>
#include <algorithm>

#define NMAX 100005
using namespace std;

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

int n, m, k = 1;
int first[NMAX];
vector <int> p2max;
vector <vector <int> > G;
vector <vector <int> > rmq;

void euler(int nod)
{
	first[nod] = k;
	rmq[0].push_back(nod); ++k;
	for (vector<int> ::iterator it = G[nod].begin(); it != G[nod].end(); ++it)
		if (!first[*it])
		{
			euler(*it);
			rmq[0].push_back(nod); ++k;
		}
}


void make_p2max()
{
	p2max.push_back(0); p2max.push_back(0);
	for (int i = 2; i < 5 * NMAX; ++i)
		p2max.push_back(p2max[i / 2] + 1);
}

void make_rmq()
{
	for (int i = 1; (1 << i) < k; ++i)
	{
		rmq.push_back(*new vector<int>);
		for (int j = 0; j + (1 << i) - 1 < k; ++j)
			rmq[i].push_back(min(rmq[i - 1][j], rmq[i - 1][j + (1 << (i - 1))]));
	}
}

int query(int x, int y)
{
	if (x > y) swap(x, y);
	int imax = p2max[y - x];
	return min(rmq[imax][x], rmq[imax][y - (1 << imax) + 1]);
}

int main()
{
	int x, y;
	fin >> n >> m;
	G.assign(n + 10, *new vector<int>);
	for (int i = 2; i <= n; ++i)
	{
		fin >> x;
		G[x].push_back(i);
		G[i].push_back(x);
	}

	rmq.push_back(*new vector<int>);
	rmq[0].push_back(0);
	euler(1);
	make_rmq();
	make_p2max();
	for (int i = 0; i < m; ++i)
	{
		fin >> x >> y;
		fout << query(first[x], first[y]) << '\n';
	}
	return 0;
}