Codeforces Round #618 (Div. 2), problem: (C) Anu Has a Function

** Anu Has a Function**

Anu has created her own function f: f(x,y)=(x|y)−y where | denotes the bitwise OR operation. For example, f(11,6)=(11|6)−6=15−6=9. It can be proved that for any nonnegative numbers x and y value of f(x,y) is also nonnegative.

She would like to research more about this function and has created multiple problems for herself. But she isn’t able to solve all of them and needs your help. Here is one of these problems.

A value of an array [a1,a2,…,an] is defined as f(f(…f(f(a1,a2),a3),…an−1),an) (see notes). You are given an array with not necessarily distinct elements. How should you reorder its elements so that the value of the array is maximal possible?

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

The second line contains n integers a1,a2,…,an (0≤ai≤109). Elements of the array are not guaranteed to be different.

Output
Output n integers, the reordering of the array with maximum value. If there are multiple answers, print any.

Examples
Input

4
4 0 11 6

Output

11 6 4 0

Input

1
13

Output

13

Note
In the first testcase, value of the array [11,6,4,0] is f(f(f(11,6),4),0)=f(f(9,4),0)=f(9,0)=9.

[11,4,0,6] is also a valid answer.
题意

本题是指给出一个数n和一个长度为n+2的数组,重新排列这个数组,使得数组进行(((x|y)-y)|z)-z这样运算后,得到的值最大。

题解

假设两个数为11,5. 他们的二进制数分别为1011,101.
按照题目中给的公式的话,就为
1011
0101
————
1111
减去0101的话就为
1111
-0101
————
1010 注意三个数的二进制
1011
0101
1010
我们可以发现在二进制中的每一位,当第二个数和第一个数的值都为一时,结果为零,当第一个为零,第二个为一时结果仍然为零,只有当第一个是一而第二个为零时,结果才为一
由此我们可以推出,将整个数组中的数字按二进制进行排列,找到一个最高位的,只有一个数是一而其他数都是零的数,所以我们这道题的题目就变为了,将数组中的所有数变为二进制,找到一个最高位只有一个数字是一而其他数字都是零的数,将这个数提在最前面,而其他数随意输出即可

#include<iostream>
#include<vector>
#include<string> 
#include<algorithm>
#include<cmath>
#include<memory>
#include<iomanip>
using namespace std;
#define ll long long
int a[1000000];
int b[1000000];
int c[1000000];
int main() {
	int n,s=0;
	cin >> n;
	int max = -1;
	for (int i = 0; i < n; i++) {
		cin >> a[i];
		c[i] = a[i];
		if (a[i] > max)max = a[i];
	}
	while (max > 0) {
		max=max >> 1;
		int k = 0;
		int flag = 0;
		for (int i = 0; i < n; i++) {
			b[i] = a[i] % 2;
			a[i] = a[i] >> 1;
		}
		for (int i = 0; i < n; i++) {
			if (b[i] == 1) {
				flag++;
				k = i;
			}
		}
		if (flag == 1)s = k;
	}
	cout << c[s]<<" ";
	for (int i = 0; i < n; i++) {
		if (i != s)cout << c[i] << " ";
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值