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:

● 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.
 

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.
 

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 题意:求[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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值