HDU 5014-Number Sequence

来源:互联网 发布:游戏聊天软件 编辑:程序博客网 时间:2024/05/16 15:15

Problem Description
There is a special number sequence which has n+1 integers. For each number in sequence, we have two rules:

● ai ∈ [0,n]
● ai ≠ aj( i ≠ j )

For sequence a and sequence b, the integrating degree t is defined as follows(“⊕” denotes exclusive or):

t = (a0 ⊕ b0) + (a1 ⊕ b1) +···+ (an ⊕ bn)


(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 ≤ 105), The second line contains a0,a1,a2,...,an.
 

Output
For each case, output two lines.The first line contains the maximum integrating degree t. The second line contains n+1 integers b0,b1,b2,...,bn. There is exactly one space between bi and bi+1(0 ≤ i ≤ n - 1). Don’t ouput any spaces after bn.
 

Sample Input
42 0 1 4 3
 

Sample Output
201 0 2 3 4

                                                                   

题意:

给出一列数只包括0~n (1<=n<=10^5)求出一个排列使得一一对应的异或值总和最大~

思路:

可以找到其规律,先写出0~10 的二进制数

0  0000 ,1  0001,2  0010,3  0011,4  0100, 5  0101,6 0110,7  0111,8  1000,9  1001, 10  1010

可以看出倘若每一个数所占的位数都为1 的话,那么得到的异或值就是最大的,而刚好得到的最大异或值减去原来的数就是得到的配对的数。

code:

#include <iostream>#include <cstdio>#include <algorithm>#include <cmath>#include <string>#include <cstring>#include <queue>#include <stack>#include <vector>#include <set>#include <map>const int inf=0xfffffff;typedef long long ll;using namespace std;int a[100005], ans[100005],n;int cal(int n){    int l = 0;    while(n){        n >>= 1;        l ++;    }    return l;}int main(){    //freopen("in", "r", stdin);    while(~scanf("%d", &n)){        memset(ans, -1, sizeof(ans));        for(int i = 0; i <= n; i ++){            scanf("%d", &a[i]);        }        ll num,t,sum = 0;        for(int i=n; i>=0; i--){            if(ans[i] == -1){                int len=cal(i);                num = (1<<len) - 1;                t = num^i;                if(ans[t] == -1){                    ans[i] = t;                    ans[t] = i;                    sum += (num*2);                }            }        }        printf("%d\n", sum);        printf("%d", ans[a[0]]);        for(int i=1;i<=n;i++){            printf(" %d", ans[a[i]]);        }        printf("\n");    }    return 0;}


0 0