Pagini recente » Cod sursa (job #3270383) | Cod sursa (job #653055) | Cod sursa (job #909162) | Cod sursa (job #2367410) | Cod sursa (job #2501078)
#include <fstream>
#include <iostream>
#include <vector>
#include <stdlib.h>
#define INF 0x3f3f3f3f
#define MAX_N 100005
#define nst (nod << 1)
#define ndr (nst | 1)
#define mij ((superiorlimit + inferiorlimit) >> 1)
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");
class lcaSegmentTrees{
private:
vector<vector<int> > graph;
vector<int> eulerAp;
vector<int> heights;
vector<int> firstApInEuler;
vector<int> segmenttree;
int eulerpoz = 0;
int solution = INF;
int heightsolution = INF;
int left ;
int right ;
public:
lcaSegmentTrees( vector<vector<int > > mygraph){
graph = mygraph;
eulerAp.resize(mygraph.size()*4 ,0);
firstApInEuler.resize(mygraph.size()*4 ,0 );
heights.resize(mygraph.size()*4 ,0);
segmenttree.resize(mygraph.size()*4,0);
}
void dfs(int nod, int height){
eulerAp[++eulerpoz] = nod;
heights[eulerpoz] = height;
firstApInEuler[nod] = eulerpoz;
for( auto it :graph[nod]){
dfs(it,height + 1);
eulerAp[++eulerpoz] = nod; // in intoarcerea din dfs se mai viziteaza nodul
heights[eulerpoz] = height;
}
}
void buildsegmenttree(int nod, int inferiorlimit, int superiorlimit ) {
if( inferiorlimit == superiorlimit ){
segmenttree[nod] = inferiorlimit;
return;
}
buildsegmenttree( nst, inferiorlimit, mij );
buildsegmenttree( ndr , mij + 1, superiorlimit );
if( heights[segmenttree[nst]] <= heights[segmenttree[ndr]] ){
segmenttree[nod] = segmenttree[nst];
//g << segmenttree[nod] <<" "<<"da";
}
else{
segmenttree[nod] = segmenttree[ndr];
}
}
void query(int nod, int inferiorlimit, int superiorlimit ) {
if( left <= inferiorlimit && superiorlimit <= right ){
if( heights[segmenttree[nod]] < heightsolution )
solution = eulerAp[segmenttree[nod]],
heightsolution = heights[segmenttree[nod]];
return;
}
if( left <= mij )
query( nst, inferiorlimit, mij);
if( mij < right)
query( ndr, mij + 1, superiorlimit);
}
int resolve( int x, int y){
left = firstApInEuler[x];
right = firstApInEuler[y];
if( left > right )
swap(left,right);
solution = INF;
heightsolution = INF;
query(1,1,eulerpoz);
return solution;
}
void getlca(vector< pair<int,int> >& queries ){
dfs(1,0);
// for(int i = 1; i <= eulerpoz; i++)
// g << heights[i] <<" ";
buildsegmenttree(1,1,eulerpoz);
// g<<"\n";
for( auto it : queries ){
g << resolve( it.first,it.second) <<"\n";
}
}
};
void lca( vector<vector<int> >& graph, vector< pair<int,int> >& queries ){
lcaSegmentTrees 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);
}