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

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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Eclipse二进制文件是指由Eclipse集成开发环境生成的可执行文件。在Linux下,Eclipse生成的二进制文件通常是没有扩展名的,如上述引用所示。在使用Eclipse编译和运行项目时,如果项目名包含扩展名(例如.hdu.c),则Eclipse可能无法正确识别该文件为二进制可执行文件。 这可能导致在运行时出现找不到二进制文件的错误。解决办法有两种:一是避免使用带有扩展名的项目名,另一种是手动创建一个运行配置,将命令写死以确保正确识别为二进制文件。 需要注意的是,上述讨论中的EclipseParser库是一个用于验证和读取Eclipse二进制文件内容的DLL库,它是通过按照二进制格式编写的。这个库可以验证和读取Eclipse二进制文件中的EGRID、INIT、UNRST等内容。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [linux下eclipse c++运行不了提示找不到二进制文件的解决方法](https://blog.csdn.net/bjrxyz/article/details/8974483)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [Eclipse油藏数值模拟软件的二进制文件格式解析](https://blog.csdn.net/slofslb/article/details/119176891)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值