Mai intai trebuie sa te autentifici.
Cod sursa(job #2497603)
Utilizator | Data | 22 noiembrie 2019 22:10:57 | |
---|---|---|---|
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;
class lcaRmq{
private:
vector<vector<int> > graph;
vector<int> eulerAp;
vector<int> heights;
vector<int> rmq[logmax + 5];
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);
}