Cod sursa(job #1815005)

Utilizator DoubleNyNinicu Cristian DoubleNy Data 24 noiembrie 2016 18:56:21
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.88 kb
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long long int lli; 
typedef pair < int, int> dbl; 
const int maxInt = 1e9*2;
const lli maxLong = 1e18*2;
int n, m, elem = 0; 
int dad[100005];
bool visited[100005];
vector <int> adj[100005];
int euler[300005], level[300005];
int info[20][300005];
int position[300005];
void DFS(int node, int depth){
	elem++;
	euler[elem] = node;
	level[elem] = depth;
	//if(position[node] == 0)
	//position[node] = elem;
	visited[node] = true;
	for(int i = 0; i < adj[node].size();i++)
		if(!visited[adj[node][i]]){
			DFS(adj[node][i], depth + 1);
			elem++;
			euler[elem] = node;
			level[elem] = depth;
	}
}
void RMQ(){
	for(int i = 1; i <= elem; i++)
			info[0][i] = i;
		for(int i = 1; (1 << i) <= elem; i++)
				for(int j = 1; j + (1 << i) - 1 <= elem; j++){
					int pw = 1 << (i-1);
					if(level[info[i - 1][j]] < level[info[i - 1][j + pw]])
						info[i][j] = info[i - 1][j];
					else 
						info[i][j] = info[i - 1][j + pw];
				}
}

int main(){
	ios::sync_with_stdio(0);
//	ifstream cin("input.in");
//	ifstream cin("lca.in");
//	ofstream cout("lca.out");
	freopen("lca.in", "r", stdin);
	freopen("lca.out", "w", stdout);
	//cin >> n >> m;
	scanf("%d %d", &n, &m);
	dad[1] = -1;
	for(int i = 2; i <= n; i++){	
		//cin >> dad[i];
		scanf("%d", &dad[i]);
		adj[dad[i]].push_back(i);
	}
	DFS(1, 0);
	RMQ();
	for(int i = 1; i<=elem;i++)
		position[euler[i]] = i;
	for(int i = 1; i <= m; i++){
			int a, b;
			scanf("%d %d", &a, &b);
			//cin >> a >> b;
			a = position[a];
			b = position[b];
			if(a > b)
				swap(a, b);
				//cout << a << ' ' << b << endl;
			int lng = b - a + 1;
			int k = (int)log2(lng);
			int pw = lng - (1 << k);
			printf("&d\n", min(euler[info[k][a]], euler[info[k][a + pw]]));
			//cout << min(euler[info[k][a]], euler[info[k][a + pw]]) << endl;
	}
//	for(int i = 1; i <= elem; i++)
//		cout << level[i] << ' ';
	return(0);
}