Cod sursa(job #1959759)

Utilizator preda.andreiPreda Andrei preda.andrei Data 9 aprilie 2017 21:23:24
Problema Lowest Common Ancestor Scor 90
Compilator c Status done
Runda Arhiva educationala Marime 2.7 kb
#include <stdio.h>
#include <stdlib.h>

#define LOG 20
#define BUFF_CAP 32768

FILE *fin, *fout;

char NextChar()
{
	static char buffer[BUFF_CAP];
	static int buff_size = 0;
	static int buff_ind = BUFF_CAP;

	if (buff_ind >= buff_size) {
		buff_size = fread(buffer, sizeof(char), BUFF_CAP, fin);
		buff_ind = 0;
	}
	return buffer[buff_ind++];
}

int NextInt()
{
	char c = NextChar();
	while (c < '0' || c > '9') {
		c = NextChar();
	}

	int num = 0;
	while (c >= '0' && c <= '9') {
		num = num * 10 + (c - '0');
		c = NextChar();
	}
	return num;
}

typedef struct ListNode
{
	int value;
	struct ListNode *next;
} ListNode;

typedef struct List
{
	ListNode *left, *right;
} List;

ListNode *CreateListNode(int value)
{
	ListNode *new_node = (ListNode*)malloc(sizeof(ListNode));
	*new_node = (ListNode){value, NULL};
	return new_node;
}

void AddToList(List *list, int value)
{
	ListNode *new_node = CreateListNode(value);
	if (list->left == NULL) {
		list->left = list->right = new_node;
	} else {
		list->right->next = new_node;
		list->right = new_node;
	}
}

typedef struct TreeNode
{
	int ancestors[LOG];
	int nanc;

	int exit;
	List sons;
} TreeNode;

TreeNode* CreateTree(int size)
{
	TreeNode *tree = (TreeNode*)malloc(size * sizeof(TreeNode));
	int i;

	for (i = 0; i < size; ++i) {
		tree[i].nanc = tree[i].exit = 0;
		tree[i].sons = (List){NULL, NULL};
	}
	return tree;
}

void Dfs(TreeNode *t, int node, int st[], int nst)
{
	static int time = 0;
	st[nst] = node;

	if (nst > 0) {
		int fa = st[nst - 1];
		int ord = 1;

		t[node].ancestors[0] = fa;
		while ((1 << ord) < nst) {
			t[node].ancestors[ord] = t[fa].ancestors[ord - 1];
			fa = t[fa].ancestors[ord - 1];
			++ord;
		}
		t[node].nanc = ord;
	}

	ListNode *it = t[node].sons.left;
	while (it != NULL) {
		Dfs(t, it->value, st, nst + 1);
		it = it->next;
	}
	t[node].exit = ++time;
}

void Swap(int *a, int *b)
{
	int aux = *a;
	*a = *b;
	*b = aux;
}

int Lca(TreeNode *t, int x, int y)
{
	if (x == y) {
		return x;
	}
	if (t[x].exit > t[y].exit) {
		Swap(&x, &y);
	}

	int pos = 0;
	int power = (1 << 5);

	while (power > 0) {
		if (pos + power < t[x].nanc) {
			int fa = t[x].ancestors[pos + power];
			if (t[fa].exit <= t[y].exit) {
				pos += power;
			}
		}
		power >>= 1;
	}
	return Lca(t, y, t[x].ancestors[pos]);
}

int main()
{
	fin = fopen("lca.in", "r");
	fout = fopen("lca.out", "w");

	int n, q, i, fa, x, y;
	n = NextInt();
	q = NextInt();

	TreeNode *tree = CreateTree(n);
	for (i = 1; i < n; ++i) {
		fa = NextInt();
		AddToList(&tree[fa - 1].sons, i);
	}

	int *stack = (int*)malloc(n * sizeof(int));
	Dfs(tree, 0, stack, 0);
	free(stack);

	while (q--) {
		x = NextInt();
		y = NextInt();
		fprintf(fout, "%d\n", Lca(tree, x - 1, y - 1) + 1);
	}
	free(tree);

	return 0;
}