codeforces 578b//"Or" Game// Codeforces Round #320 (Div. 1)

题意:n个数字,最多操作k次,每次乘x,要使结果数组的与值最大。

能推断出结果是对一个元素操作k次,并且这个元素的二进制最高位比较大。并不一定是取最大的,比如1100和1010,乘以一次2,两种选法分别为11000|1010=11010,;;;1100|10100=11100后者更大。

有没有可能k次乘在不同的数字上呢?不可能。如果有3个数字abc二进制最高位都是第5位,k=3,x=2,假如乘了一次a,再乘两次a,与的结果是8位。如果放弃a,去乘别的,只有7位以下。

实现过程中,用一个数组arr记录每个位的出现数。比如9是1001,那么++arr[0],++arr[3]。对当前元素,减掉它的贡献,加上乘法操作后的贡献,然后与起来看是不是更大,最后输出最大的。

乱码:

//#pragma comment(linker,"/STACK:1024000000,1024000000")
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
#include <stack>
#include <iomanip>
using namespace std;
const int SZ=,INF=0x7FFFFFFF;
const double EPS=1e-;
typedef long long lon; int arr[];
lon num=; int main()
{
std::ios::sync_with_stdio();
lon maxv=,maxid=;
//freopen("d:\\1.txt","r",stdin);
//for(;scanf("%d",&n)!=EOF;)
{
lon n,k,x;
cin>>n>>k>>x;
vector<lon> vct;
for(int i=;i<n;++i)
{
lon tmp;
cin>>tmp;
vct.push_back(tmp);
}
for(int i=;i<n;++i)
{
lon cur=vct[i];
for(int j=;(num<<j)<=cur;++j)
{
if(cur&(num<<j))
{
++arr[j];
}
}
}
for(int i=;i<n;++i)
{
lon cur=vct[i];
lon res=;
for(int j=;(num<<j)<=cur;++j)
{
if(cur&(num<<j))
{
--arr[j];
}
}
for(int j=;j<;++j)
{
if(arr[j])
{
res|=(num<<j);
}
} lon a=cur;
for(int j=;j<k;++j)
{
a*=x;
} res|=a;
//cout<<res<<endl;
if(res>maxv)
{
maxv=res;
maxid=i;
} for(int j=;(num<<j)<=cur;++j)
{
if(cur&(num<<j))
{
++arr[j];
}
}
} lon res=;
for(int i=;i<n;++i)
{
if(i!=maxid)
{
res|=vct[i];
}
else
{
res|=maxv;
}
}
cout<<res<<endl;
}
return ;
}
上一篇:leetcode Insert Interval 区间插入


下一篇:HDOJ1005 数列