Question:
Given a string of numbers, pre [I] (the variance of the previous I number or) is a [0] ~ A [I-1] exclusive or, post [I] (suffix exclusive or) is a [I] ~ Returns the exclusive or of a [n-1] and returns the maximum value of pre [I] ^ post [J] (0 <= I <= j <= N, pre [0] = 0, post [N] = 0 (indicating that no number is selected ).
Method: Use the trie tree to store the suffix or prefix. First, start from pre [N] and traverse forward. For each prefix, add the suffix to the trie tree, in trie, find the value that is different from the current prefix or get the maximum value. When the trie is used to store the number, each bit of the binary number of The number is stored. Because it is impossible to increase the number of digits after the XOR or, if we want to find the maximum value, you only need to start from the first place and make sure that this bit can be set to 1. If you cannot set a value to 0, the final result must be the largest. The trie tree used here is a non-pointer version .. I wrote it myself and thought the pointer was too complicated (I was too weak...). I used the method of storing the lower mark of the node.
Note that when storing data, you need to store all 40 BITs (2 ^ 40 is the first power of 10 ^ 12). Otherwise, the number of processing bits will be very troublesome. In this case, the maximum number of node points in the trie tree is 40*10 ^ 5, which is also feasible. Since the number range is 10 ^ 12, int will be cracked, long is used,
Be especially careful! Operations such as (1 <40) will blow up the int type, and must be written as (1ll <40.The blogger has been in trouble for a long time .. If it weren't for a big bull's reminder, I wouldn't know when to discover this problem... It is also possible to get rid of the rewrite !...
For details, see the code and comments:
# Include <iostream> # include <cstdio> # include <algorithm> # include <cstring> # define n 100010 using namespace STD; struct node {long NXT [2]; // store the subscript of the NXT node in the array} trie [N * 40]; long all_idx, bit [42], num [N], n; long createnode () {memset (trie [all_idx]. NXT,-1, sizeof (trie [all_idx]. NXT); // if you have not accessed it, set it to-1 return all_idx ++;} void insert_node (long root, long cur) {memset (bit, 0, sizeof (BIT); // stores the binary number of cur L Ong long Len = 0; while (cur) {bit [Len ++] = cur & 1; cur >>=1 ;} long idx = root; // store all 40 BITs in for (LEN = 40; Len> = 0; Len --) {long K = bit [Len]; If (trie [idx]. NXT [k] =-1) trie [idx]. NXT [k] = createnode (); idx = trie [idx]. NXT [k] ;}} long running (long root, long cur) {long sum = 0; memset (bit, 0, sizeof (BIT )); long long Len = 0; while (cur) {bit [Len ++] = cur & 1; cur >>=1 ;} long idx = root; For (LEN = 4 0; Len> = 0; Len --) {long K =! Bit [Len]; // The two numbers are different. The variance or result is 1 If (trie [idx]. NXT [k]! =-1) {sum + = (1ll <Len); // you must add ll for a long time... It is also speechless. idx = trie [idx]. NXT [k];} else idx = trie [idx]. NXT [! K]; // if such a number does not exist, it can only take 0 and go down from here.} Return sum;} int main () {scanf ("% i64d", & N); long pre = 0, post = 0; long ans = 0; for (long I = 0; I <n; I ++) scanf ("% i64d", num + I), pre ^ = num [I]; long long root = createnode (); For (long I = n-1; I> = 0; Pre ^ = num [I], post ^ = num [I], I --) {insert_node (root, post); ans = max (ANS, running (root, pre);} ans = max (ANS, running (root, pre )); // determine the cout value when the 0 prefixes are obtained <ans <Endl; return 0 ;}
Codeforces 282e. Sausage maximization [trie tree (non-pointer version )]