CF-579 D. "Or" Game

题意:

给一列数,任选一个数,乘x,最多操作k次,问最后a[1]|a[2]|...|a[n]的最大值是多少;

思路:

或运算是0|0=0,1|0=1,0|1=1,1|1=1,那么每次乘一个大于等于2的数就能使最高位数增加,那么肯定是把k个x都乘在一个数上才能最大,把a[1]|...|a[n]的前后缀都找出来,暴力枚举要找的那个数,得到最大值就好了。

 蛮好的一个方法,保存前缀和后缀的和

 比赛的时候由于思维定式把or看成xor了,甚至连给的公式都没有扳回我僵化的思维

#include
#include
#define maxn 200010
using namespace std;
int a[maxn],n,k,x;
long long nxt[maxn],pre[maxn],base=1,ans,sum;
long long solve(int id){
    long long res=0;
    res=pre[id-1]|nxt[id+1]|(1LL*a[id]*base);
    return res;
}
int main(){
    scanf("%d%d%d",&n,&k,&x);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        sum|=a[i];
        pre[i]=pre[i-1]|a[i];
    }ans=sum;
    for(int i=n;i>=1;i--){
        nxt[i]=nxt[i+1]|a[i];
    }
    while(k--)
        base=1LL*base*x;
    for(int i=1;i<=n;i++){
        long long now=solve(i);
        if(now>ans)ans=now;
    }
    cout<endl;
    return 0;
}

 

你可能感兴趣的:(CF-579 D. "Or" Game)