CF 578B "Or" Game

漫长的考研生活终于结束了 结局是戏剧性的以保研之路结束 在这里感谢那些给予我机会的优等生 不管如何 结局是好的 我既然拥有了这个机会 我就要好好把握 好久没更新这个博客了  之后有时间K题目的话 我会继续更新博客。


B. "Or" Game
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

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.

Input

The first line contains three integers nk and x (1 ≤ n ≤ 200 0001 ≤ k ≤ 102 ≤ x ≤ 8).

The second line contains n integers a1, a2, ..., an (0 ≤ ai ≤ 109).

Output

Output the maximum value of a bitwise OR of sequence elements after performing operations.

Sample test(s)
input
3 1 2
1 1 1
output
3
input
4 2 3
1 2 4 8
output
79
Note

For the first sample, any possible choice of doing one operation will result the same three numbers 112 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 12472 so the OR value will be 79 and is the largest possible result.


操作为乘法  给人第一的想法自然是最大的数字一直乘 得到的结果自然是最大的 于是马上写了一份代码交了上去 光荣的WA了  仔细一想 其实应该是二进制底下拥有最高位的数字 都有这个机会 反正最终结果肯定是一个数字用光所有操作 然后或之后的结果就是最优了 所以也不用管什么数字应该被操作了 直接每个数字试一遍 用位运算纪录每一位的增益情况 就不会超时 具体细节看代码吧。


代码:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<ctime>
#include<string>
#include<cstring>
#include<algorithm>
#include<fstream>
#include<queue>
#include<stack> 
#include<vector>
#include<cmath>
#include<iomanip>
#define rep(i,n) for(i=1;i<=n;i++)
#define MM(a,t) memset(a,t,sizeof(a))
#define INF 1e9
typedef long long ll;
#define mod 1000000007     
using namespace std;
ll a[200020];
int wei[100];
int n,k,x;
void pushfun(ll num,int val){
  int i,j;
  i=0;
  while(num){
    j=num%2;
	i++;
	wei[i]+=val*j;
	num/=2;	
  }	
}
ll cal(){
  int i,j;
  ll res=0,t=1;
  for(i=1;i<=64;i++){
    if(wei[i]>=1) res+=t;
	t=t*2;	
  }	
  return res;
}
int main(){
	int i,j;
	ll ans,res;
	
	while(scanf("%d%d%d",&n,&k,&x)!=EOF){
	  MM(wei,0); ans=0;
	  rep(i,n){
        scanf("%I64d",&a[i]);
        pushfun(a[i],+1);
  	  }
	  rep(i,n){
	  	ll tmp=a[i];
  	    pushfun(a[i],-1);
		for(j=1;j<=k;j++) tmp=tmp*x;
		pushfun(tmp,+1);
		ans=max(ans,cal());
		pushfun(tmp,-1);
		pushfun(a[i],+1);
  	  }
	  printf("%I64d\n",ans);
	}
	
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值