异或与乘积题解
题目描述
有 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 ai≥1 所以不用管。还有一种就是 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;
}