首页 > 代码库 > HDU - 5014 Number Sequence

HDU - 5014 Number Sequence


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
4 2 0 1 4 3
 

Sample Output
20 1 0 2 3 4题意:求[0, n]的两个排列两两异或和的最大值思路:算的上是一道规律题吧,拿5:101来说,能异或到的最大的数是111,那么就有(101,10)和(100,11)这两种,那么我们依次推下去求解就是比如:0,1,2,3,4,5对应的值是:1,0,5,4,3,2,可以比较容易看到规律
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <vector>
typedef __int64 ll;
//typedef long long ll;
using namespace std;
const int maxn = 100005;

ll ans[maxn];
int n;

int cal(int m) {
	int len = 0;
	while (m) {
		m >>= 1;
		len++;
	}
	return len;
}

ll init(int m) {
	ll sum = 0;
	while (m >= 0) {
		int len = cal(m);
		ll Max = (ll)(1<<len) - 1;
		for (int i = Max-m; i <= m; i++)
			ans[i] = Max - i;
		sum += (ll)(m-(Max-m)+1) * Max;
		m = Max - m - 1;
	}
	return sum;
}

int main() {
	while (scanf("%d", &n) != EOF) {
		memset(ans, 0, sizeof(ans));
		ll sum = init(n);
		printf("%I64d\n", sum);

		int x;
		for (int i = 0; i <= n; i++) {
			scanf("%d", &x);
			if (i == 0)
				printf("%I64d", ans[x]);
			else printf(" %I64d", ans[x]);
		}
		printf("\n");
	}
	return 0;
}


HDU - 5014 Number Sequence