Cod sursa(job #246847)

Utilizator doizeceAdi Bass doizece Data 21 ianuarie 2009 17:35:59
Problema Xor Max Scor 100
Compilator c Status done
Runda Arhiva de probleme Marime 1.9 kb
#include <stdio.h>
#include <stdlib.h>

/* FIXME: verifica daca-i mai rapida o parcurgere urmata de un lookup sau o
 * parcurgere cu generare */

/* FIXME: verifica data un trie cu pointeri este mai rapid/incet decat un trie
 * salvat intr-un vector */

typedef struct Trie {
	int cargo;
	struct Trie* next[2];
} Trie;

/* allocate and zero a new trie */
Trie* new_trie() {
	Trie *nt = (Trie *)malloc(sizeof(Trie));
	nt->cargo = 0;
	nt->next[0] = nt->next[1] = 0;
	return nt;
}

/* insert into trie overwritting current value */
Trie* insert_into_trie(Trie *t, int k, int c) {
	int i, n;
	for (i = 1<<21; i; i >>= 1) {
		n = (k & i) ? (1) : (0);
		if (!t->next[n])
			t->next[n] = new_trie();
		t = t->next[n];
	}
	t->cargo = c;
	return t;
}

int pos, opp;

/* find the maximum bitwise opposite of the key in the trie */
/* SETS: pos, opp */
void find_max(Trie *t, int k) {
	int i, n, v = 0;
	for (i = 1<<21; i; i >>= 1) {
		n = (k & i) ? (0) : (1); /* reversed from above */
		if (!t->next[n])
			n = 1 - n;
		if (n)
			v += i;
		t = t->next[n];
	}
	pos = t->cargo;
	opp = v;
}

int main(int argc, char *argv[]) {
	int n, i, aux, sofar = 0;
	int max = -1, maxs = 0, maxf = 0;

	Trie *t = new_trie();
	insert_into_trie(t, 0, 0);

	FILE *fi = fopen("xormax.in", "r");
	fscanf(fi, "%d", &n);
	for (i = 1; i <= n; ++i) {
		fscanf(fi, "%d", &aux);
		sofar ^= aux; /* (N, xor) is a commutative monoid */
		/* printf("%d -> ", sofar); */
		find_max(t, sofar);
		/* printf("%d (%d..%d)\n", sofar ^ opp, pos+1, i); */
		if ((sofar ^ opp) > max) { /* (N, xor) is a commutative monoid */
			max = sofar ^ opp;
			maxs = pos+1;
			maxf = i;
		}
		insert_into_trie(t, sofar, i);
		/* because i_i_t overwrites, f_m will find the most recent pos */
	}
	fclose(fi);

	FILE *fo = fopen("xormax.out", "w");
	fprintf(fo, "%d %d %d\n", max, maxs, maxf);
	fclose(fo);

	return 0;
}