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

题意:给出范围N,给出0-N的一个排列a。让你求出另外一个排列b,使 t = a1 ^ b1 + a2 ^ b2 + ...+an ^ bn(^表示异或)最大。并求出最大的t。

先满足大的数,也就是从n到0进行处理,

#include <iostream>
#include <cstdio>
using namespace std;
int map[]={0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535,131071};
int main()
{
    int n;
    int a[100001];
    int b[100001];
    while (scanf("%d",&n)!=EOF)
    {
        for (int i=0; i<=n; i++)
        {
            scanf("%d",&a[i]);
        }
        int k=0;
        while (map[k]<=n)
        {
            k++;
        }
        int right=0,left=0;
        right=n;
        while (right>=0)
        {
            while ((right^map[k])>=right && k>0)
            {
                k--;
            }
            left=right^map[k];
            for (int i=right; i>=left; i--)
            {
                b[i]=i^map[k];
            }
            k--;
            right=left-1;
        }
        long long sum=0;
        for (int i=0; i<=n; i++)
        {
            sum+=a[i]^b[a[i]];
        }
        cout<<sum<<endl;
        for (int i=0; i<n; i++)
        {
            cout<<b[a[i]]<<" ";
        }
        cout<<b[a[n]]<<endl;
    }
    return 0;
}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值