Cod sursa(job #2779114)

Utilizator AACthAirinei Andrei Cristian AACth Data 2 octombrie 2021 18:36:57
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.29 kb
#include <bits/stdc++.h>
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");
#define cin f
#define cout g
const int Max = 1e5 + 1;
void nos()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
}
namespace SparseTables{
	const int Lmax = 1e6;
	struct Node{
		int depth;
		int node;
	} ST[21][Lmax];
	int n;
	Node merge(Node a, Node b)
	{
		//edit merge for diferent function
		if(a.depth < b.depth)
			return a;
		return b;
	}
	void Init(std::vector< Node > v)
	{
		int i,j;
		n = v.size() - 1;
		for(i=0;i<=n;++i)
			ST[0][i] = v[i];
		for( i = 1; (1<<i) - 1 <= n;++i){
			for(j = 0; j + (1<<i) - 1 <= n;++j)
				ST[i][j] = merge(ST[i-1][j],ST[i-1][j + (1<<(i-1))]);
		}	
	}
	Node ConstantQuery(int left, int right)
	{
		//check if it works
		if(left > right)
			swap(left,right);
		int k = log2(right-left+1);
		return merge(ST[k][left],ST[k][right - (1<<k) + 1]);
	}
}
namespace LCA{
	vector < SparseTables::Node > parcurg;
	bitset < Max > viz;
	vector < int > first_apar;
	vector < int > last_apar;
	void dfs(int node, int depth,vector < int > Graph[])
	{
		viz[node] = true;
		parcurg.push_back({depth,node});
		first_apar[node] = parcurg.size() - 1;
		for(auto vec : Graph[node])
			if(viz[vec] == false)
		{
			dfs(vec,depth + 1,Graph);
			parcurg.push_back({depth,node});
		}
		last_apar[node] = parcurg.size() - 1;
	}

	void precompute(vector < int > Graph[], int n)
	{
		parcurg.clear();
		first_apar.resize(n + 1);
		last_apar.resize(n + 1);
		for(int i=1;i<=n;i++)
		{
			first_apar[i] = last_apar[i] = -1;
			viz[i] = false;
		}
		
		int root = 1;
		dfs(root,1,Graph);
		SparseTables::Init(parcurg);
	}
	int get_LCA(int n1,int n2)
	{
		int left = min(first_apar[n1],first_apar[n2]);
		int right = max(last_apar[n1],last_apar[n2]);
		return SparseTables::ConstantQuery(left,right).node;
	}
}
int n,q;
vector < int > v[Max];
void read()
{
	f>>n>>q;
	for(int i=2;i<=n;i++)
	{
		int parent;
		f>>parent;
		v[parent].push_back(i);
	}
}
void solve()
{
    LCA::precompute(v,n);
    while(q -- )
    {
    	int n1,n2;
    	f>>n1>>n2;
    	cout<<LCA::get_LCA(n1,n2)<<'\n';
    }
}
void restart()
{

}
int32_t main()
{
    nos();

        read();
        solve();
        restart();
    
    return 0;
}