What could be the most optimized solution to this problem and please also suggest some variations in this problems which I can prepare.
This problem can be solved using Trie data structure with time complexity( N * Bits_size ) , where size of bit is depend on constraint , if elements are in the range of integer , then the time complexity should be O(N * 32 )
Step 1 : First insert Nth element in the tire , then insert xor ( A[ N ] , A[ N - 1 ] ) , then xor ( A[N] , A[N-1] , A[N-2] ) ans so on… till the 1st element.
And make an array suffix , where suffix[i] = xor( Array[i] , Array[i + 1] … Array[N]);
Now, to calculate answer , start from starting index , and remove the contribution of suffix[i] from the trie , and find the maximum xor we can obtained from the trie with prefix[i] , where prefix[i] = xor( Array[1] , Array[2] … Array[i] ) and from that we should be able to calculate the maximum xor value of suffix[i] with prefix[j] , where 1 <= i < j <= N with complexity ( N * Bit_size )
Here, I am assuming that the prefix and suffix we are considering are not overlap means for any prefix the starting index of suffix should be greater the ending index of prefix.
First learn Trie data structure , then i will provide the source code
Implementation:
#define vipsharmavip
#include<bits/stdc++.h>
#define ll long long
using namespace std;
struct trie{
int ct;
struct trie *left , *right;
trie(): ct(0),left(NULL),right(NULL) {}
};
void Insert( trie *root , int level , int x , int change ){
if(level < 0 )
return;
if( (x & (1 << level)) == 0 ){
if(root->left == NULL )
root->left = new trie();
root->left->ct += change;
Insert( root->left , level - 1 , x , change );
} else {
if(root->right == NULL )
root->right = new trie();
root->right->ct += change;
Insert( root->right , level - 1 , x , change );
}
}
ll query(trie * root , int level , int x ){
if(root == NULL )
return 0;
if(level < 0 )
return 0;
if((1 << level) & x ){
if(root->left != NULL ){
if(root->left->ct)
return (1 << level ) + query( root->left , level - 1 , x );
else
return query( root->right , level - 1 , x );
} else
return query( root->right , level - 1 , x );
} else
{
if(root->right != NULL ){
if(root->right->ct)
return (1 << level ) + query( root->right , level - 1 , x );
else
return query( root->left , level - 1 , x );
} else
return query( root->left , level - 1 , x );
}
}
int main(){
trie *root = new trie();
cin.sync_with_stdio(false);
int N;
cin >> N;
int Array[N];
for(int i = 0 ; i < N ; ++i ) cin >> Array[i];
int sufffix[N+1];
int xr = 0;
for(int i = N - 1 ; i >= 0 ; --i ){
xr = (xr ^ Array[i]);
sufffix[i] = xr;
Insert(root , 30 , xr , 1 );
}
int Ans = 0;
xr = 0;
for(int i = 0 ; i < N - 1; ++i ){
Insert(root , 30, sufffix[i] , -1 ); // remove the contribution of suffix starting from ith index
xr = (xr ^ Array[i]);
int value = query( root , 30 , xr );
Ans = max(Ans , value );
}
cout << Ans << endl;
return 0;
}