Codeforces Round #477 (rated, Div. 2, based on VK Cup 2018 Round 3) E. Big Secret

E. Big Secret
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Vitya has learned that the answer for The Ultimate Question of Life, the Universe, and Everything is not the integer 54 42, but an increasing integer sequence a1,,ana1,…,an. In order to not reveal the secret earlier than needed, Vitya encrypted the answer and obtained the sequence b1,,bnb1,…,bn using the following rules:

  • b1=a1b1=a1;
  • bi=aiai1bi=ai⊕ai−1 for all ii from 2 to nn, where xyx⊕y is the bitwise XOR of xx and yy.

It is easy to see that the original sequence can be obtained using the rule ai=b1biai=b1⊕…⊕bi.

However, some time later Vitya discovered that the integers bibi in the cypher got shuffled, and it can happen that when decrypted using the rule mentioned above, it can produce a sequence that is not increasing. In order to save his reputation in the scientific community, Vasya decided to find some permutation of integers bibi so that the sequence ai=b1biai=b1⊕…⊕bi is strictly increasing. Help him find such a permutation or determine that it is impossible.

Input

The first line contains a single integer nn (1n1051≤n≤105).

The second line contains nn integers b1,,bnb1,…,bn (1bi<2601≤bi<260).

Output

If there are no valid permutations, print a single line containing "No".

Otherwise in the first line print the word "Yes", and in the second line print integers b1,,bnb1′,…,bn′ — a valid permutation of integers bibi. The unordered multisets {b1,,bn}{b1,…,bn} and {b1,,bn}{b1′,…,bn′} should be equal, i. e. for each integer xx the number of occurrences of xx in the first multiset should be equal to the number of occurrences of xx in the second multiset. Apart from this, the sequence ai=b1biai=b1′⊕…⊕bi′ should be strictly increasing.

If there are multiple answers, print any of them.

Examples
input
Copy
3
1 2 3
output
Copy
No
input
Copy
6
4 7 7 12 31 61
output
Copy
Yes
4 12 7 31 7 61 
Note

In the first example no permutation is valid.

In the second example the given answer lead to the sequence a1=4a1=4a2=8a2=8a3=15a3=15a4=16a4=16a5=23a5=23a6=42a6=42.

题解:
对于当前的异或值x,若要使x变大,只需使其中一位从0变为1,
且比这一位大的不变,比这一位小的任意变化。
因此保存每个数的最高位的1,然后从x的地位开始遍历,若遍历
到某一位是0,且存在一个数使之变为1,则取出这个数。
代码:
#include<cstdio>
#include<queue>
using namespace std;
#define ll long long
const int maxn=1e5+7;
ll a[maxn],b[maxn];
queue<ll>p[66];
int main()
{
	int n;scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		scanf("%lld",&a[i]);
		for(int j=60;j>=0;j--)
		{
			if(a[i]>>j&1)
			{
				p[j].push(a[i]);
				break;
			}
		}
	}
	bool bb=1;
	ll x=0;
	for(int i=1;i<=n;i++)
	{
		bb=0;
		for(int j=0;j<=60;j++)
		{
			if(!(x>>j&1)&&!p[j].empty())
			{
				bb=1;b[i]=p[j].front();p[j].pop();
				x^=b[i];
				break;
			}
		}
		if(!bb)break;
	}
	if(!bb)printf("No\n");
	else
	{
		printf("Yes\n");
		for(int i=1;i<=n;i++)
			printf("%lld%c",b[i],i==n?'\n':' ');
	}
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值