Pagini recente » Cod sursa (job #2142775) | Cod sursa (job #693348) | Cod sursa (job #2933791) | Cod sursa (job #1524001) | Cod sursa (job #50360)
Cod sursa(job #50360)
#include <assert.h>
#include <stdio.h>
enum { maxn = 100001, maxd = 21 };
int n, p[maxn];
int depth, mask;
int leaf, tab[maxd], restab[maxd];
int result, position;
int ans, start, end;
int news; //mem stats
int d;
void pd()
{
for(int i = 0; i < d; i++) printf(" ");
}
struct item
{
int pos; //only if leaf
item *zero, *one;
} root;
void fill_tab(int val)
{
for(int i = 0; i < depth; i++) {
if(val & (1 << i)) tab[i] = true;
else tab[i] = false;
}
}
void add(item *p, int pos)
{
assert(p != NULL);
assert(pos >= 0);
item **kid;
if(tab[pos]) kid = &(p->one);
else kid = &(p->zero);
if(*kid == NULL) {
(*kid) = new item;
(*kid)->zero = NULL;
(*kid)->one = NULL;
(*kid)->pos = -2;
news++;
}
if(pos == 0) (*kid)->pos = leaf;
else add(*kid, pos - 1);
}
inline void trie_add(int num, int pos)
{
fill_tab(num);
leaf = pos;
add(&root, depth - 1);
}
void find(item *p, int pos)
{
assert(p != NULL);
if(pos == -1) {
assert(p->pos != -2);
assert(p->zero == NULL);
assert(p->one == NULL);
position = p->pos;
result = 0;
for(int i = 0; i < depth; i++)
if(restab[i]) result |= 1 << i;
}
else {
assert(pos >= -1);
if(p->zero && p->one) {
if(tab[pos]) {
restab[pos] = 1;
find(p->one, pos - 1);
}
else {
restab[pos] = 0;
find(p->zero, pos - 1);
}
}
else if(p->zero) {
restab[pos] = 0;
find(p->zero, pos - 1);
}
else {
assert(p->one);
restab[pos] = 1;
find(p->one, pos - 1);
}
}
}
inline void damnlies(int query) //searches the trie for the best match
{
fill_tab(query);
#ifndef NDEBUG
result = -2;
position = -2;
#endif
find(&root, depth - 1);
assert(result != -2);
assert(position != -2);
}
int main()
{
int i, max = 0, x;
FILE *f = fopen("xormax.in", "r");
if(!f) return 1;
fscanf(f, "%d", &n);
for(i = 0; i < n; i++) {
fscanf(f, "%d", &p[i]);
if(p[i] > max) max = p[i];
}
for(depth = maxd; depth; depth--)
if((1 << (depth - 1)) <= max) break;
mask = (1 << depth) - 1;
fclose(f);
f = fopen("xormax.out", "w");
if(!f) return 1;
trie_add(0, -1);
x = 0;
for(i = 0; i < n; i++) {
x ^= p[i];
trie_add(x, i);
}
ans = -1; //zero is a valid answer and we must find it if it's the best
x = 0;
for(i = 0; i < n; i++) {
x ^= p[i];
damnlies((~x) & mask);
if((x ^ result) > ans && position < i) {
ans = x ^ result;
start = position;
end = i;
printf("ans %d start %d end %d\n", ans, start, end);
}
}
assert(ans != -1);
fprintf(f, "%d %d %d\n", ans, start + 2, end + 1);
fclose(f);
return 0;
}