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=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;
}

猜你喜欢

转载自www.cnblogs.com/gaudar/p/9640730.html