Codeforces Round #618 (Div. 2)C. Anu Has a Function(思维 + 二进制)

题目链接
题意给你n个数,之后定义一个函数f(x, y) = (x | y) - y,让你求f(f(…f(f(a1,a2),a3),…an−1),an)最大的a_1-a_n的顺序
思路:其实我们可以发现f(x, y) = (x|y) - y可以等价于x - (x & y)即减去x和y二进制相同位的位置,那么我们可以很快的发现如果a_1-a_n
结论:如果一个二进制位出现了大于1次,得到的最大值二进制1在这一位是一定不存在的,那么我们可以直接求出来最后的最大值,接下来就是调出a_1-a_n的顺序

解法:我们只需要不断把二进制1只出现一次且当前最大值最大的数放在前面就好了。

#include<bits/stdc++.h>
#define ll long long
#define sc scanf
#define pr printf
#define pii pair<int,int>
#define x first
#define y second
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
using namespace std;
const int maxn = 1e5 + 5;
int a[maxn],n,bit[100];
int main(){
	IOS; 
	cin >> n;
	for(int i = 1; i <= n; i++)cin >> a[i];
	if(n == 1){
		cout << a[1] << endl;
		return 0;
	}
	// x - x & y 
	ll mx = 0;
	for(int i = 1; i <= n; i++){
		for(int j = 31; j >= 0; j--){
			if(a[i] >> j & 1)bit[j]++;
			//求出a_i的所有二进制1 
		}
	}
	for(int i = 1; i <= n; i++){
		ll now = 0;
		for(int j = 0; j <= 31; j++){
			//如果当前a_i二进制1存在 且当前所有数的二进制1只有一个
			//那么答案 += 1ll << j  如果二进制1出现两次
			//那么当前这个二进制一定会减少 所以不需要更新 
			if((a[i] >> j & 1) && bit[j] == 1)now += (1ll << j);
		}
		if(now >= mx)mx = now, swap(a[i], a[1]);
	}
	for(int i = 1; i <= n; i++){
		if(i == 1)cout << a[i];
		else cout << ' ' << a[i];
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值