HDU 5014
传送门
题意:给你一个0~n的序列,求另一个0~n的序列,使得
的值最大。(这里的“+”是指a[i]^b[i])
分析
要使值最大,如4的二进制是100,则要使其变为111,这样4就要与3异或,那么3自然要与4异或,往后多写几个数就会发现,它们会两两配对。所以,就用贪心从大往小遍历一次,即可得到答案。(注意:奇数和偶数的配对方式不一样,当n位奇数时,有偶数个数,可以两两配对,但n为偶数时,有奇数个数,那么就使0与自己配对即可)
算法的正确性
因为保证了单元的a[i]^b[i]最大,所以所得的和必然最大
代码如下:
#include<stdio.h>
#include<string.h>
#define ll long long
int a[100005],b[100005],n;
ll sum,num,tot;
int main()
{
while(~scanf("%d",&n))
{
sum=0;
memset(b,-1,sizeof(b));
for(int i=0;i<=n;i++)
scanf("%d",&a[i]);
for(int i=n;i>=0;i--)
if(b[i]==-1)
{
for(tot=1;tot<=i;tot<<=1);//求比i大的2^k次方
tot--;
num=tot^i;
sum+=tot*2;
b[i]=num;
b[num]=i;
}
printf("%I64d\n",sum);
for(int i=0;i<=n;i++)
printf(i==n?"%d\n":"%d ",b[a[i]]);
}
return 0;
}