根据亦或的性质,要获得最大的和,那么两两配对的数的二进制数的每一位都不相同,所以会形成一种对称的局势.
比如1111到0000之间就是两两对称
1010和0101之间也是两两对称,
根据这种性质,那么只要利用hash提前预处理出配对的数,然后求解就好了
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <iostream>
#define MAX 300007
using namespace std;
int n;
int a[MAX],b[MAX];
int hash[MAX];
int main ( )
{
while ( ~scanf ( "%d" , &n ) )
{
for ( int i = 0 ; i <= n ; i++ ) scanf ( "%d" , &a[i] );
memset ( hash , 0 , sizeof ( hash ) );
int temp = n;
int total = 1;
hash[0] = 0;
while ( temp > 0 )
{
total = 1;
while ( total <= temp ) total<<=1;
total--;
int next = (total^temp)-1;
while ( 1 )
{
hash[temp^total] = temp;
hash[temp] = temp^total;
if ( (temp^total)+1 == temp ) break;
temp--;
}
temp = next;
}
long long ans = 0;
for ( int i = 0 ; i <= n ; i++ )
{
b[i] = hash[a[i]];
ans += b[i]^a[i];
}
printf ( "%I64d\n" , ans );
for ( int i = 0 ; i < n ; i++ ) printf ( "%d " , b[i] );
printf ( "%d\n" , b[n] );
}
}