Cod sursa(job #2280369)

Utilizator herbertoHerbert Mohanu herberto Data 10 noiembrie 2018 15:16:19
Problema Lowest Common Ancestor Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.1 kb
#include<bits/stdc++.h>
using namespace std;
#define MAXN 100001
#define MAXP 20

vector <pair<int, int> > sol;
vector<int> g[MAXN];
int first[MAXN];
int d[2][2*MAXN][MAXP];
int lung;
int lg[2*MAXN];

int minim(int a, int b){
  if(a<b)
    return a;
  return b;
}
int maxim(int a, int b){
  if(a>b)
    return a;
  return b;
}


void rmq(){
	int p, i;
	for(p=1; (1<<p)<lung; p++){
    for(i=1; i-1+(1<<p)<=lung; i++){
			if(d[0][i][p-1]<d[0][i+(1<<p-1)][p-1]){
				d[0][i][p]=d[0][i][p-1];
				d[1][i][p]=d[1][i][p-1];
			}
			else{
				d[0][i][p]=d[0][i+(1<<p-1)][p-1];
				d[1][i][p]=d[1][i+(1<<p-1)][p-1];
			}
    }

  }
}

void dfs(int nod, int niv){
	int i;
	sol.push_back({nod, niv});
	if(first[nod]==0)
		first[nod]=sol.size()-1;
	for(i=0; i<g[nod].size(); i++){
		dfs(g[nod][i], niv+1);
		sol.push_back({nod, niv});
		if(first[nod]==0)
			first[nod]=sol.size()-1;
	}
}
int main(){
	FILE*fin=fopen("lca.in", "r");
	FILE*fout=fopen("lca.out", "w");
	int n, m, i, j, a, b, ans;
	fscanf(fin, "%d%d", &n, &m);
	for(i=1; i<=n-1; i++){
		fscanf(fin, "%d", &a);
		g[a].push_back(i+1);
	}
	sol.push_back({0, 0});
	dfs(1, 1);
	lung=sol.size()-1;
	for(i=1; i<=lung; i++){
//		printf("%d %d %d\n", i, sol[i].first, sol[i].second);
    d[0][i][0]=sol[i].first;
    d[1][i][0]=i;
	}
//	for(i=1; i<=lung; i++)
//    printf("%d ", i);
//  printf("\n");
//	for(i=1; i<=lung; i++)
//    printf("%d ", sol[i].first);
//  printf("\n");
//  for(i=1; i<=lung; i++)
//    printf("%d ", sol[i].second);
//  printf("\n");
  rmq();
//  int p;
//  for(p=0; (1<<p)<lung; p++){
//    for(i=1; i<=lung; i++)
//      printf("%d ", d[1][i][p]);
//    printf("\n");
//  }
	lg[1]=0;
	for(i=2; i<=lung; i++)
		lg[i]=lg[i/2]+1;

  for(m; m>0; m--){
		fscanf(fin, "%d%d", &a, &b);
		i=minim(first[a], first[b]);
		j=maxim(first[a], first[b]);
//		printf("%d %d %d %d\n", a, b, i, j);
		if(d[0][i][lg[j-i]]<d[0][j-(1<<lg[j-i])+1][lg[j-i]])
			ans=d[1][i][lg[j-i]];
		else
			ans=d[1][j-(1<<lg[j-i])+1][lg[j-i]];

		fprintf(fout, "%d\n", sol[ans].first);
  }
	return 0;
}