edit
I implemented the list (ideone) if anyone's interested, gotta practice c when I can...
typedef struct {
int count;
int capacity;
int *indexes; // position (i.e. j) where number is
} INDEXLIST;
typedef struct NODE_STRUCT {
struct NODE_STRUCT *left, *right;
int minIndex, maxIndex;
int value; // for a leaf
INDEXLIST *indexList; // for a leaf
} NODE;
So when loading the x1..xN, I populate the tree starting at bit 14 and going left for a 0 and right for a 1, expanding minIndex
and maxIndex
for all the nodes in the path and only populating value
and indexList
for the final node.
When searching for a maximum value, I traverse the tree in the order of looking for the highest resulting xored value. For instance if bit 14 of the a
value is 1, I go left first looking for x
values with a 0 in that position. If bit 13 is 0, I then go right first looking for an x
with a 1
in that position. It traverses the tree in the order to maximize the resulting xored value, so when I reach a leaf that contains an index in range, I return the value I've built-up based on those left-right choices which will be the original inserted value xored with the a
value passed.
NODE *add_index_to_node(NODE *node, int index, int value, int depth);
int find_largest(NODE *node, int value, int minIndex, int maxIndex, int depth);
while (T--) {
scanf("%d %d", &N, &Q);
for (i = 1; i <= N; i++) {
scanf("%d", &x);
root = add_index_to_node(root, i, x, 0);
}
for (i = 0; i < Q; i++) {
scanf("%d %d %d", &a, &p, &q);
result = find_largest(root, a, p, q, 0);
printf("%d\n", result);
}
// free memory
free_node(root);
root = NULL;
}
A unique value could have 96+ bytes of overhead not including the other tree nodes, but it could handle more bits with just recompiling and is a lot more efficient at sparse lists than my first try...