Cod sursa(job #761189)

Utilizator hello4242Mihai Paulescu hello4242 Data 25 iunie 2012 07:12:44
Problema Xor Max Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.15 kb
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cassert>
#define S 21 

using namespace std;

struct node {
    char bit;
    int who;
    int children[2];
} trie[2100000];
int nodecount;

int a[100010], prefix[100010];

// int traverse(int id, int level) {
//     int i;
// 
//     if ( id == 1 ) printf("X\n");
//     else {
//         for (i=1; i<=level; ++i) printf("| ");
//         printf("%d (%d)\n", trie[id].bit, id);
//     }
// 
//     if ( trie[id].children[0] ) traverse(trie[id].children[0], level+1);
//     if ( trie[id].children[1] ) traverse(trie[id].children[1], level+1);
// }

void insert(int u, int bitcount, int id, int me) {
    int curbit, next;

    if ( bitcount < 0 ) return ;

    curbit = ( u & (1 << bitcount) ) != 0;

    if ( trie[id].children[curbit] == 0 ) {
        nodecount++;
        trie[id].children[curbit] = nodecount;
        trie[nodecount].bit = curbit;
    }

    if ( bitcount == 0 ) {
        next = trie[id].children[curbit];
        if ( !trie[next].who ) trie[next].who = me;
    }

    insert(u, bitcount-1, trie[id].children[curbit], me);
}

int curb;

int query(int u) {
    int next, ans = 0, i, curbit, id = 1;

    for (i=S; i>=0; i--) {
        curbit = ( u & (1 << i) ) != 0;

        if ( trie[id].children[curbit^1] == 0 ) {
            next = trie[id].children[curbit];
        }
        else {
            next = trie[id].children[curbit^1];
        }

        ans ^= (1 << trie[next].bit);
        id = next;
    }

    curb = trie[id].who;
    return ans;
}

int main(void) {
    freopen("xormax.in", "r", stdin);
    freopen("xormax.out", "r", stdout);
    int N, i, ans = 0, cur, ansb, anse;

    scanf("%d", &N);

    for (i=1; i<=N; ++i) {
        scanf("%d", &a[i]);
        prefix[i] = prefix[i-1]^a[i];
    }

    nodecount = 1;
    insert(0, S, 1, 1);

    for (i=1; i<=N; ++i) {
        /* traverse(1, 0); */
        cur = prefix[i]^query(prefix[i]);

        if ( cur > ans ||
            (cur == ans && curb < ansb )) {
            ans = cur;
            ansb = curb;
            anse = i;
        }
        insert(prefix[i], S, 1, i+1);
    }

    printf("%d %d %d\n", ans, ansb, anse);

    return 0;
}