题意: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=1000010,INF=0x7FFFFFFF; const double EPS=1e-8; typedef long long lon; int arr[70]; lon num=1; int main() { std::ios::sync_with_stdio(0); lon maxv=0,maxid=0; //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=0;i<n;++i) { lon tmp; cin>>tmp; vct.push_back(tmp); } for(int i=0;i<n;++i) { lon cur=vct[i]; for(int j=0;(num<<j)<=cur;++j) { if(cur&(num<<j)) { ++arr[j]; } } } for(int i=0;i<n;++i) { lon cur=vct[i]; lon res=0; for(int j=0;(num<<j)<=cur;++j) { if(cur&(num<<j)) { --arr[j]; } } for(int j=0;j<70;++j) { if(arr[j]) { res|=(num<<j); } } lon a=cur; for(int j=0;j<k;++j) { a*=x; } res|=a; //cout<<res<<endl; if(res>maxv) { maxv=res; maxid=i; } for(int j=0;(num<<j)<=cur;++j) { if(cur&(num<<j)) { ++arr[j]; } } } lon res=0; for(int i=0;i<n;++i) { if(i!=maxid) { res|=vct[i]; } else { res|=maxv; } } cout<<res<<endl; } return 0; }