You are given n numbers a1, a2, ..., an. You can perform at most k operations. For each operation you can multiply one of the numbers by x. We want to make as large as possible, where denotes the bitwise OR.
Find the maximum possible value of after performing at most k operations optimally.
The first line contains three integers n, k and x (1 ≤ n ≤ 200 000, 1 ≤ k ≤ 10, 2 ≤ x ≤ 8).
The second line contains n integers a1, a2, ..., an (0 ≤ ai ≤ 109).
Output the maximum value of a bitwise OR of sequence elements after performing operations.
3 1 2 1 1 1
3
4 2 3 1 2 4 8
79
For the first sample, any possible choice of doing one operation will result the same three numbers 1, 1, 2 so the result is .
For the second sample if we multiply 8 by 3 two times we'll get 72. In this case the numbers will become 1, 2, 4, 72 so the OR value will be 79 and is the largest possible result.
题目大意:
给你N个数,最多可以进行k次操作,每次操作可以选择一个数,使得其变成a【i】*x.
问最终所有数或的值最大是多少。
思路:
1、考虑到或操作的特性:有1的位子上结果就是1.
那么很显然,我们希望得到的结果最大,就要使得最高位尽可能的高。
2、要使得最高位尽可能的高,那么我们希望的就是将K次操作都赋予一个数上,那么这个数一定这个数组中的最大值吗?
显然不是,对于乘法操作中,因为还有*3.*5......这类的操作,就是说在提升最高位的同时,还能使得较小位子上边的1升高。
所以显然不是这个数组中的最大值,那么这个数到底是谁最优呢?
其实我们并不需要太纠结于这个问题。
因为我们可以枚举这个数。
那么我们O(n)枚举出来一个数,将K次操作都赋予这个数上,然后可以通过位压缩的方式,来暴力统计哪些位子上有1.
那么这里可以将O(n^2)的暴力枚举时间复杂度降到O(n*64);
3、细节处理好,注意数据范围。
Ac代码:
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;
#define ll __int64
ll a[1005000];
ll po[100];
int have[100];
ll poww(ll a,ll b)
{
return po[b];
}
void add(ll num,int d)
{
for(int j=0;j<64;j++)
{
ll tm=poww(2,j);
if((num&tm)!=0)
{
have[j]+=d;
}
}
}
int main()
{
ll n,k,x;
while(~scanf("%I64d%I64d%I64d",&n,&k,&x))
{
memset(have,0,sizeof(have));
for(int i=0;i<n;i++)
{
scanf("%I64d",&a[i]);
}
ll tmp=1;
for(int i=0;i<64;i++)
{
if(i==0)po[i]=1;
else po[i]=po[i-1]*2;
}
for(int i=0;i<k;i++)
{
tmp*=x;
}
for(int i=0;i<n;i++)
{
for(int j=0;j<64;j++)
{
ll tm=poww(2,j);
if((a[i]&tm)!=0)
{
have[j]++;
}
}
}
ll output=0;
for(int i=0;i<n;i++)
{
add(a[i],-1);
a[i]*=tmp;
add(a[i],1);
ll sum=0;
for(int j=0;j<64;j++)
{
if(have[j]>0)sum+=(ll)poww(2,j);
}
output=max(output,sum);
add(a[i],-1);
a[i]/=tmp;
add(a[i],1);
}
printf("%I64d\n",output);
}
}