B. "Or" Game

B. "Or" Game

题意

给你N个数,最多可以进行k次操作,每次操作可以选择一个数,使得其变成a[i]*x。

问最终所有数或的值最大是多少。

思路
  1. 考虑到或操作的特性:有1的位置上结果就是1。

    那么很显然,我们希望得到的结果最大,就要使得最高位尽可能的高。

  2. 要使得最高位尽可能的高,那么我们希望的就是将K次操作都赋予一个数上,那么这个数一定这个数组中的最大值吗?

    显然不是,就是说在提升最高位的同时,还能使得较小位子上边的1升高(感性理解一下)。

    所以显然不是这个数组中的最大值,那么这个数到底是谁最优呢?

    其实我们并不需要太纠结于这个问题。

    因为我们可以通过前缀或数组和后缀或数组枚举这个数。

    第i个数 a[i]进行这k次操作,(记m=x^k)那么结果就是\(pre[i-1] | (a[i]*m) | nxt[i+1]\)然后暴力枚举出最大值就是了。

代码实现
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e6+10;
ll a[maxn];
ll pre[maxn];
ll nxt[maxn];
int main(void){
    int n,k,x;
    cin >> n >> k >> x;
    for(int i = 1; i <= n; i++) cin >> a[i];
    for(int i = 1; i <= n; i++) pre[i] = pre[i-1]|a[i];
    for(int i = n; i >= 1; i--) nxt[i] = nxt[i+1]|a[i];
    ll m = 1;
    for(int i = 1; i <= k; i++) m *= x;
    ll ans = 0;
    for(int i = 1; i <= n; i++){
        ans = max(ans,pre[i-1]|(a[i]*m)|nxt[i+1]);
    }
    cout<<ans<<endl;
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/AC-AC/p/12443971.html