题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5014
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.
● 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):
(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.
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
Source
线下 AC的,比赛的时候其实已经找到规律了,然后自己二呵呵的把binary数组初值赋错了,一直没发现....粗糙党
不过后来看正解是贪心...但我们的规律也是按贪心找的...
思路:
如果两个数的二进制位数不同,这两个数的异或值就会越大,所以尽量使 a^b == 2^x - 1,这样我们得到了一个基本关系。
a: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ...
b: 0 2 1 4 3 10 9 8 7 6 5 20 19 18 17 16 15 14 ...
可以看出从17~11是递增,10~5也是递增的,4~3是递增的,2~1递增,如果a是上限,那么直接找2^x - 1 >= a,这里=a ,只有第一次累加的时候,然后一次往回加,加到小于上一次的最小值....重复这个过程...我用了low和high来完成累加的过程,并标记每一次的上下限
代码:
#include <algorithm>
#include <cstdlib>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cctype>
#include <cmath>
#include <stack>
#include <queue>
#include <list>
#include <map>
#include <set>
using namespace std;
#define min2(x, y) min(x, y)
#define max2(x, y) max(x, y)
#define min3(x, y, z) min(x, min(y, z))
#define max3(x, y, z) max3(x, max(y, z))
#define clr(x, y) memset(x, y, sizeof(x))
#define fr(i,n) for(int i = 0; i < n; i++)
#define fr1(i,n) for(int i = 1; i < n; i++)
#define upfr(i,j,n) for(int i = j; i <= n; i++)
#define dowfr(i,j,n) for(int i = n; i >= j; i--)
#define scf(n) scanf("%d", &n)
#define ptf(n) printf("%d",n)
#define ptfl(n) printf("%I64d",n)
#define ptfs(s) printf("%s",s)
#define ptk() printf(" ")
#define ptln() printf("\n")
#define srt(a,n) sort(a,n)
#define LL long long
#define pi acos(-1.0)
#define inf 1 << 31-1
#define eps 0.00001
#define maxn 100005
int arr[maxn];
int ans[maxn];
int binary[maxn];
int vis[maxn];
int main()
{
//freopen("in.txt","r",stdin);
binary[0] = 1; //2的0次是1,开始自己写成2了,2333
fr1(i,20)
binary[i] = binary[i-1] * 2;
int n;
while(scf(n) !=EOF )
{
clr(vis,0);
clr(ans,0);
clr(arr,0);
fr(i,n+1)
scf(arr[i]);
int tmp;
fr(i,20)
{
if(binary[i] > n)
{
tmp = binary[i];
break;
}
}
//ptf(tmp);
int low,high;
low = tmp - 1 - n;
ans[n] = low;
high = n;
dowfr(i,0,n-1)
{
if(ans[i+1]+1 == n)
ans[i] = n;
else if(ans[i+1] + 1 < high)
ans[i] = ans[i+1] + 1;
else
{
fr(j,20)
{
if(binary[j] > i)
{
high = low ;
low = binary[j] - 1 - i;
break;
}
}
ans[i] = low;
}
}
__int64 sum = 0;
fr(i,n+1)
sum += i ^ ans[i];
ptfl(sum);
ptln();
ptf(ans[arr[0]]);
upfr(i,1,n)
ptk(),ptf(ans[arr[i]]);
ptln();
}
return 0;
}