异或与乘积题解

异或与乘积题解

题目描述

n n n 个数你可以将两个数字异或,最终将所有数字相乘,问总乘积最大是多少

由于答案可能很大,输出对 1000000007 1 000 000 007 1000000007​ 取模后的结果。

思路概述

首先,我们需要了解一个问题:异或是什么东西?异或简单来说0就是而进制中的加法,也就是不同就是 1 1 1 ,如果相同就是 0 0 0 。好的,那我们就可以了解一个事情,异或肯定小于等于加法,加法小于乘法,但是,有两种情况会出现反例,什么呢?就是有 0 0 0 的情况,但是不难发现, a i ≥ 1 a_{i} \ge 1 ai1 所以不用管。还有一种就是 a i = 1 a_{i}=1 ai=1 那么如果他异或偶数,那么就 + 1 +1 +1 ,不然就 − 1 -1 1 。所以我们就先分离出 1 1 1 的位置,然后利用和一定,差小积大的特点,把小的偶数先拿过去异或就可以了。

#include<bits/stdc++.h>
using namespace std;
const int Mod=1e9+7;
int a[100010];
int b[100010];
int main()
{
	int n;
	cin>>n;
	long long ans=1;//一定要注意开long long 不然死得很惨。
	int cnt=0;
	int len=1;
	int len1=1;
	for(int i=1;i<=n;i++)//分离奇数和偶数,记录1的个数
	{
		int x;
		cin>>x;
		if(x==1)
		{
			cnt++;
		}
		else
		{
			if(x&1)
			{
				a[len++]=x;
			}
			else
			{
				b[len1++]=x;
			}
		}
	}
	sort(b+1,b+len1);
	for(int i=1;i<len1;i++)//开始异或
	{
		if(cnt-1>=0)
		{
			cnt--;
			b[i]+=1;
		}
	}
	for(int i=1;i<len1;i++)
	{
		ans=1LL*(ans*b[i])%Mod;
	}
	for(int i=1;i<len;i++)
	{
		ans=1LL*(ans*a[i])%Mod;
	}
	cout<<ans<<endl;
	return 0;
}
  • 15
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值