题意:
给你n个数,b[1],b[2],b[3].......,让你重新排列,使a[i]的值递增
a[i]和b的关系:
a[i] = b[1]^b[2]^b[3]^....^b[i];
首先说异或 因为是递增,所以1^0 0^0 1^1都不满足条件
只有0^1满足条件
1^0 == 1 相当于没有增长
0^1 == 1 这才相当于增长了1
再看 a=00 01 01 10
b=00 10 11 10
这两个二进制数a,b进行异或
对于第一位 大家都等于0 异或出来相当于没变
第二位 大家都等于1 异或出来相当于少1
第三位。。。。。
第四位 a第四位等于0 b第四位等于1 两个数异或 相当于b的这一位没有改变
第五位 a第五位等于1 b第五位等于0 两个数异或 b的这一位变成1
所以只要选择a的最高位等于1 b的这一位等于0的情况进行异或
但是为什么要选择最高位:
因为只要最高位进行了增加 比他低的位无论加1还是减1都不会影响异或后的大小关系
可惜就是这样我也没想出来,想到了0和1的异或关系和一位一位去算
但是没做出来 可惜了
#include <iostream>
#include <cstdio>
#include <string>
#include <vector>
#include <cstring>
#include <cstdlib>
#include <algorithm>
using namespace std;
const long long maxn = 2e5+;
const long long N = (long long)<<;
long long a[maxn];
long long b[maxn];
vector<long long> bit[];
int main()
{
long long n,i,j,k;
long long x;
scanf("%lld",&n);
for(i=;i<n;++i)
{
scanf("%lld",b+i);
x = ;
for(j = ;j>=;--j)
{
if((x<<j)&b[i])
{
bit[j].push_back(b[i]);
break;
}
}
}
x = ;
for(i=;i<n;++i)
{
bool flag = false;
for(j=;j<;++j)
{
if(((x&((long long)<<j)) == ) && bit[j].size())
{
a[i] = bit[j][bit[j].size()-];
x ^= bit[j][bit[j].size()-];
bit[j].pop_back();
flag = true;
break;
}
}
if(!flag)
{
printf("No\n");
return ;
}
}
printf("Yes\n");
for(i=;i<n;++i)
printf("%lld ",a[i]);
}