Problem Description
There is a special number sequence which has n+1 integers. For each number in sequence, we have two rules:
● a i ∈ [0,n]
● a i ≠ a j( i ≠ j )
For sequence a and sequence b, the integrating degree t is defined as follows(“⊕” denotes exclusive or):
t = (a
0 ⊕ b
0) + (a
1 ⊕ b
1) +···+ (a
n ⊕ b
n)
(sequence B should also satisfy the rules described above)
Now give you a number n and the sequence a. You should calculate the maximum integrating degree t and print the sequence b.
● a i ∈ [0,n]
● a i ≠ a j( i ≠ j )
For sequence a and sequence b, the integrating degree t is defined as follows(“⊕” denotes exclusive or):
(sequence B should also satisfy the rules described above)
Now give you a number n and the sequence a. You should calculate the maximum integrating degree t and print the sequence b.
Input
There are multiple test cases. Please process till EOF.
For each case, the first line contains an integer n(1 ≤ n ≤ 10 5), The second line contains a 0,a 1,a 2,...,a n.
For each case, the first line contains an integer n(1 ≤ n ≤ 10 5), The second line contains a 0,a 1,a 2,...,a n.
Output
For each case, output two lines.The first line contains the maximum integrating degree t. The second line contains n+1 integers b
0,b
1,b
2,...,b
n. There is exactly one space between b
i and b
i+1
(0 ≤ i ≤ n - 1). Don’t ouput any spaces after b
n.
Sample Input
4 2 0 1 4 3
Sample Output
20 1 0 2 3 4
</pre><br /><br /><p></p>
题意:
给出的 0 - n 之间的数字,求出它们异或的和的最大;
任意的数字 ,例如 0 1 0 1,以其异或的值最大是 1 0 1 0;
因此 我们就 可以通过 0 1 0 1 异或 1 1 1 1 得到 1 0 1 0;
那么就可以求出各自对应的值;
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#define ll __int64
#define N 100005
using namespace std;
int a[N];
int vis[N];
int b[N];
int main() {
int n;
while (scanf("%d",&n) != EOF) {
memset(a,0,sizeof(a));
memset(vis,0,sizeof(vis));
memset(b,0,sizeof(b));
for (int i = 0; i <= n; i++)
scanf("%d",&a[i]);
for (int i = n; i > 0; i--) { // 逆序
if (vis[i] == 0 ) {
int d = log2(i) + 1 ; // 为了求出求位数,例如 i = 8 ;d = 4
int t1 = ((1 << d) - 1);// 位数减去1,可以得到该位数的11……1; t1 = 15 ;(111)
int t = t1 ^ i; //求出与他异或的值
b[i] = t;
b[t] = i;
vis[i] = 1;
vis[t] = 1;
}
}
ll sum = 0;
for (int i = 0; i <= n; i++)
sum += i ^ b[i];
printf("%I64d\n",sum);
for (int i = 0; i < n; i++)
printf("%d ",b[a[i]]);
printf("%d\n",b[a[n]]);
}
}