Cod sursa(job #2497600)

Utilizator lucian2015blaugranadevil lucian2015 Data 22 noiembrie 2019 22:05:37
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.9 kb
#include <fstream>
#include <iostream>
#include <vector>
#include <stdlib.h>
#define logmax 19
using namespace std;

ifstream f("lca.in");
ofstream g("lca.out");

const int nmax = 1e5;
	vector<int> rmq[logmax + 5];
class lcaRmq{
private:
	vector<vector<int> > graph;
	vector<int> eulerAp;
	vector<int> heights;

public:
	lcaRmq(vector<vector<int> > mygraph){
		graph = mygraph;
		eulerAp.resize(nmax + 5,0);
		heights.resize(nmax + 5,0);
	}
	void dfs(int nod, int height){
		heights[nod] = height + 1;
		eulerAp[nod] = rmq[0].size();
		rmq[0].push_back(nod);
		for( auto it : graph[nod]){
			dfs( it, height + 1);
			rmq[0].push_back(nod);
		}
	}
	int GetLowerHeight( int x, int y){
		return heights[x] < heights[y] ? x : y;
	}
	void BuildRmq(){
		for( int i = 1; i <= logmax; i++ ){
			if( ( 1 << i) > rmq[0].size() )
				break;
        for(int j = 0; j < rmq[0].size(); j++)
            if(j + (1 << i) > rmq[0].size())
                break;
            else
                rmq[i].push_back(GetLowerHeight(rmq[i - 1][j], rmq[i - 1][j + (1 << (i - 1))]));
		}
	}

int QueryRmq(int x, int y)	{
    x = eulerAp[x];
    y = eulerAp[y];
    if(x > y)
        swap(x, y);
    int l = y - x + 1;
    int k = 0;
    while((1 << k) <= l)
        k++;
    k--;	
    return GetLowerHeight(rmq[k][x], rmq[k][y - (1 << k) + 1]);
	
}
	void getlca(vector< pair<int,int> > queries ){
		dfs(1,0);
		BuildRmq();
		for( auto it : queries ){
			g << QueryRmq( it.first, it.second ) <<" \n";
		}
		
	}

};


void lca( vector<vector<int> >& graph, vector< pair<int,int> >& queries ){
	lcaRmq mylca(graph);
	mylca.getlca(queries);
}

int main(){
int x, nod, y, n, m;
vector< pair< int, int > > queries;
f >> n >> m;
vector<int> parents(n + 1, 0);
vector< vector < int> > graph(n + 1);
for( int i = 2; i <=  n; i++){
	f >> parents[i];
  graph[parents[i]].push_back(i);
}
for( int i = 1; i <= m; i++ ){
	f >> x >> y;
	queries.push_back({x,y});
 }
 lca(graph,queries);

}