Cod sursa(job #476852)

Utilizator marius.bucurBucur Marius - Ovidiu marius.bucur Data 12 august 2010 15:08:32
Problema Xor Max Scor 0
Compilator c Status done
Runda Arhiva de probleme Marime 2.95 kb
#include<stdio.h>
#include<stdlib.h>

#define MAX_BIN_LIST 220
#define min(a, b) (a<b?a:b)
#define max(a, b) (a>b?a:b)

int N;
int* vec;
int* partial;

int read() {
	FILE* f = fopen("xormax.in", "r");
	if(!f)
		return 0;
	fscanf(f, "%d", &N);
	int i;
	vec = (int*) malloc(N * sizeof(int));
	partial = (int*) malloc(N * sizeof(int)); 
	for(i = 0; i < N; i++)
		fscanf(f, "%d", &vec[i]);
	fclose(f);
	return 1;
}

int partial_sol() {
	int i = 0;
	partial[0] = vec[0];
	for(i = 1; i < N; i++) {
		partial[i] = partial[i-1] ^ vec[i];
	}
	return 0;
}

void print_vec() {
	int i = 0;
	for(i = 0; i < N; i++) {
		printf("%d ", vec[i]);
	}
	printf("\n");
	for(i = 0; i < N; i++) {
		printf("%d ", partial[i]);
	}
	printf("\n");
}

struct bintrie {
	struct bintrie* left;
	struct bintrie* right;
	int* value;
	int k;
};

typedef struct bintrie bintrie_t;

struct bintrie* new_trie() {
	struct bintrie* node = (struct bintrie*) calloc(1,sizeof(struct bintrie));
	node->value = (int*)calloc(MAX_BIN_LIST, sizeof(int));
	return node;
}

void insert(bintrie_t* root, int value, int index) {
	int i = 30;
	bintrie_t* cur = root;
	for(i = 30; i >= 0; i--) {
		if(value & 1 << i) {
			//right
			if(!cur->right) {
				cur->right = new_trie();
			}
			cur = cur->right;
		}
		else {
			//left
			if(!cur->left) {
				cur->left = new_trie();
			}
			cur = cur->left;
		}
	}
	cur->value[cur->k++] = index;
}

bintrie_t* root;

void insert_trie() {
	root = new_trie();
	int i = 0;
	for(i = 0; i < N; i++)
		insert(root, partial[i], i);
}

int get_compl(int value, int** index, int* len) {
	int i = 30;
	struct bintrie* cur = root;
	int result = 0;
	for(i = 30; i >= 0; i--) {
		if(value & 1 << i) {
			if(cur->left) {
				cur = cur->left;
			}
			else {
				cur = cur->right;
				result |= 1 << i;
			}
		}
		else
			if(cur->right) {
				cur = cur->right;
				result |= 1 << i;
			}
			else {
				cur = cur->left;
			}
	}
	*index = cur->value;
	*len = cur->k;
	return result;
}

void solve() {
	int i = 0;
	int start=0,end=0,max=0;
	for(i = 0; i < N; i++) {
		int* index;
		int len;
		int compl = get_compl(partial[i], &index, &len);
		if(compl ^ partial[i] > max) {
			start = min(i, index[0]);
			end = max(i, index[0]);
			max = compl ^ partial[i];
		}
	}
	FILE* f = fopen("xormax.out", "w");
	fprintf(f, "%d %d %d\n", max, start + 2, end + 1);
	fclose(f);
}

void write() {
}

void print_trie(struct bintrie* root, int value, int depth) {
	struct bintrie* cur = root;
	printf("%*c%d %d\n", depth*2, ' ', value, cur->value[0]);
	if(cur->right) {
		print_trie(cur->right, 1 << (30 - depth) | value, depth + 1);
	}
	if(cur->left) {
		print_trie(cur->left, value, depth + 1);
	}
}

void print_compl(int n) {
	int* aux;
	int len;
	int result = get_compl(n, &aux, &len);
	printf("[%d %d", n, result);
	int i = 0;
	for(i = 0; i < len; i++)
		printf(" %d", aux[i]);
	printf("]\n");
}

int main(int argc, char** argv) {
	read();
	partial_sol();
	insert_trie();
	//print_trie(root, 0, 0);
	solve();
	write();
	print_vec();
	//print_compl(18);
}