HDU 5014 Number Sequence(二进制+区间贪心)

标签: 二进制 贪心
11人阅读 评论(0) 收藏 举报
分类:

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

Output

20
1 0 2 3 4

解题思路

1.题意假设给定自然数序列ai,ai ∈ [0,n] ,ai ≠ aj( i ≠ j ),求自然数序列bi,使ai与bi对应位上的每一个数进行异或运算后相加和最大
2.怎么才能使异或运算之后相加和最大,显然采用贪心策略,使每一个对应位异或后能取得最大值。所以重点在于怎么求出与那位数异或能取得最大值。
3.例如序列0 1 2 3 4 5 6 7 8 9 10转化成二进制00000000 00000001 00000010 00000011 00000100 00000101 00000110 00000111 00001000 00001001 00001010,不难发现当转化为二进制时每一位互补时能取得最大值,如00001010和00000101,00001001和00000110,00001000和00000111,并且可以发现是在一个区间内两两对应,因为当5(00000101)和10(00001010)互补时,5+1(00000110)和10-1(00001001)也互补。
4.所以问题转化成怎么求互补数的问题,这里需要二进制的知识,首先找出第一个比给定数字n大的数,这个数必须是2的倍数,所以比10大的且是2的倍数的数是16(00010000),然后16-1(00001111),再将n按位取反~n(11110101)后进行按位与运算&,得到与n(10)互补的数c(5)(00000101),所以这样一个区间就解决了,剩下的只需要重复此过程就可以

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<memory.h>
#include<algorithm>
using namespace std;
const int N=100005;
int a[N],b[N];
long long int sum;
void f(int n){
    if(n<=0){
        return;
    }
    int k=0;
    while((1<<k)<=n)k++;
    //求比n大的数,这个数是2的倍数,10->16
    //1<<k,就是2^k
    int cur=1<<k;
    int c=~n&(cur-1);//求与n互补的数
    for(int i=n,j=c;i>j;j++,i--){
        b[i]=j;
        b[j]=i;
        sum+=(i^j)*2;
    }
    if(cur!=0){//进行下一个区间
        f(c-1);
    }
}
int main(){
    int n;
    while(scanf("%d",&n)!=EOF){
        sum=0;
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        for(int i=0;i<=n;i++){
            scanf("%d",&a[i]);
        }
        f(n);
        printf("%lld\n",sum);
        for(int i=0;i<=n;i++){
            printf("%d%c",b[a[i]],(i==n)?'\n':' ');
        }
    }
    return 0;
}
查看评论

hdu 5014 Number Sequence(贪心)

题目链接:hdu 5014 Number Sequence 题目大意:给定n,表示有0~n这n+1个数组成的序列a,要求构造一个序列b,同样是由0~n组成,要求∑ai⊕bi尽量大。 解题思...
  • u011328934
  • u011328934
  • 2014-09-15 19:29:38
  • 814

HDU-5014-Number Sequence

Problem Description There is a special number sequence which has n+1 integers. For each number in...
  • faithdongdong
  • faithdongdong
  • 2014-09-15 00:27:02
  • 1503

HDU5014Number Sequence(贪心)

题目链接 题目大意: 给出n,然后给出一个数字串,长度为n + 1, 范围在[0, n - 1].然后要求你找出另外一个序列B,满足上述的要求,并且使得t = A0^B0 + Ai + 1 ^ Bi...
  • u012997373
  • u012997373
  • 2014-09-17 10:25:25
  • 876

HDU-#5014 Number Sequence(贪心+构造)

题目大意:给定数列以及数列值的范围,求该范围内另一个数列,使得两个数列对应位的异或和最大。      解题思路:就是对于每一个数要尽量避免自己的二进制位上的1被异或掉,也尽量要让0异或为1。推一下就...
  • qinlumoyan
  • qinlumoyan
  • 2014-09-14 22:06:02
  • 289

HDU 5014 Number Sequence(贪心)

当时想到了贪心,但是不知为何举出了反列。。。。我是逗比,看了点击打开链接。才发现我是逗比。 Problem Description There is a special number ...
  • u013582254
  • u013582254
  • 2014-09-16 01:34:43
  • 1660

贪心-HDU 5014 Number Sequence

思路: 对于每一个数字的二进制是唯一的,所以他的反也是唯一的(除符号位)。这样0 ^ 1 = 1 可以使的所有数字取得最大值。 (之前写的时候判断了 下是否有重复的,看了下网上代码发现想多了。。)...
  • qq_33951440
  • qq_33951440
  • 2016-10-14 10:49:21
  • 120

hdu 5014 number sequence 贪心

代码: #include #include #include #include using namespace std; int get_lentgh(const int& n) { ...
  • alpc_paul
  • alpc_paul
  • 2014-09-15 17:07:52
  • 406

hdu 5014 Number Sequence (贪心)

Number Sequence Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) ...
  • u011721440
  • u011721440
  • 2014-09-16 18:45:10
  • 750

HDU 1711 Number Sequence kmp算法

题目:http://acm.hdu.edu.cn/showproblem.php?pid=1711 题意:给定两个数组,问能不能再第一个数组中匹配得到第二个数组,如果可以,那么输出最早匹配的起始位置...
  • discreeter
  • discreeter
  • 2016-07-23 19:13:47
  • 756

HDU 1711Number Sequence(KMP算法详解)

转载请注明出处:http://blog.csdn.net/a1dark 分析:KMP模板题、KMP的关键是求出next的值、先预处理出next的值、然后一遍扫过、复杂度O(m+n)、 #inc...
  • verticallimit
  • verticallimit
  • 2013-10-03 05:34:48
  • 2887
    个人资料
    持之以恒
    等级:
    访问量: 607
    积分: 294
    排名: 26万+
    文章存档
    最新评论