Cod sursa(job #2426170)

Utilizator ajeccAjechiloae Eugen ajecc Data 26 mai 2019 15:21:01
Problema Lowest Common Ancestor Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.06 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <deque>
#include <set>
#include <map>
#include <unordered_map>
#include <list>
#include <array>
#include <cstdlib>
#include <stack>
#include <string>
#include <queue>
#include <chrono>
#include <functional>
#include <limits>
#include <cmath>
#include <algorithm>
#include <random>
#include <regex>
#include <tuple>
#include <utility>
#include <bitset>
#include <complex>
#include <iomanip>
#include <ostream>
#include <sstream>
#include <ctime>
#include <cassert>
using namespace std;
#define for0(i, n) for(int i = 0; i < n; i++)
#define for1(i, n) for(int i = 1; i <= n; i++)
#define pb push_back
#define mp make_pair
#define all(v) v.begin(), v.end()
#define V vector<int>
#define VP vector<pair<int, int> >
#define FASTIO ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define index INDEX
#ifndef ONLINE_JUDGE
#define print(x) PRINT(x, #x)
template<typename T> inline const void PRINT(T VARIABLE, const string& NAME) {
	cerr << NAME << " = " << fixed << VARIABLE << "\n";
}
#else
#define print(x) 0 
#endif
#ifdef RAND_MAX
#undef RAND_MAX
#endif
#define RAND_MAX 999999937 
int generate_random() {
	const int MAX_RANDOM = (int)1e6;
	mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
	return uniform_int_distribution<int>(0, MAX_RANDOM)(rng);
}
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
const ll INFLL = 2 * (ll)1e18 + 100;
//#define int ll
#ifdef int 
const int INFINT = INFLL;
#else
const int INFINT = 2 * (int)1e9 + 100;
#endif
const double PI = atan(1) * 4;
const double EPS = 1e-6;
const int SEED = (int)1e3 + 7;
const int MOD = (int)1e9 + 7;
const int NMAX = (int)1e5 + 5;
 
const int BMAX = 20;
int n, m;
V tree[NMAX];
int depth[NMAX];
int parent[NMAX][BMAX];
 
void dfs(int nod, int p, int d = 1) // NOTE: have to start from 1
{
	depth[nod] = d;
	parent[nod][0] = p;
	for(int j = 1; j < BMAX; j++)
	{
		parent[nod][j] = parent[parent[nod][j - 1]][j - 1];
	}
	for(auto i: tree[nod]) if(i != p)
	{
		dfs(i, nod, d + 1);
	}
}
 
int lca(int l, int r)
{
	if (depth[l] < depth[r]) swap(l, r);
	for (int i = BMAX - 1; i >= 0; i--) if (depth[parent[l][i]] >= depth[r]) l = parent[l][i];
	if (l == r) return l;
	for(int i = BMAX - 1; i >= 0; i--)
	{
		if(parent[l][i] != parent[r][i])
		{
			l = parent[l][i];
			r = parent[r][i];
		}
	}
	return parent[l][0];
}
 
int32_t main() {
#ifndef ONLINE_JUDGE
	double START_PROGRAM = clock();
#endif
	srand(time(0));
	cout << setprecision(20) << fixed;
	FASTIO;
	ifstream cin("lca.in");
	ofstream cout("lca.out");
	cin >> n >> m;
	for(int i = 2; i <= n; i++)
	{
		int p;
		cin >> p;
		tree[i].pb(p);
		tree[p].pb(i);
	}
	dfs(1, 0, 1);
	while(m--)
	{
		int a, b;
		cin >> a >> b;
		cout << lca(a, b) << '\n';
	}
 
 
 
#ifndef ONLINE_JUDGE
	double END_PROGRAM = clock();
	double ELAPSED_TIME = (END_PROGRAM - START_PROGRAM) / CLOCKS_PER_SEC;
	cerr << "\n\nElapsed Time: " << ELAPSED_TIME * 1000 << "\n";
#endif
	return 0;
}