题意
现在有n个数(a_1,a_2,a_3,...,a_n) 。你最多可以进行k次操作,每次操作你可以将其中一个数乘以(x),使得(a_1|a_2|...|a_n) 最大。
算法
贪心+前缀后缀
思路
首先明确:答案的这(k)次( imes x)操作用都会在同一个数身上。因为(x)大于(2),所以每次相乘都会使得该数的二进制为至少左移一位,或起来以后必然会使答案更优。
如何快速求出每一个数操作之后的答案?
利用前缀后缀思想,维护前缀或与后缀或,这样就可以在枚举出修改的数以后(O(1))求出答案了。
参考代码
#include <cstdio>
#include <algorithm>
#define LL long long
using namespace std;
const int maxn = 2e5 + 10;
int n,a[maxn],k,x;
LL pre[maxn],bac[maxn],Ans;
int main(){
scanf("%d%d%d", &n, &k, &x);
for(int i = 1; i <= n; ++ i) scanf("%d", a + i);
for(int i = 1; i <= n; ++ i) pre[i] = pre[i - 1] | a[i];
for(int i = n; i >= 1; -- i) bac[i] = bac[i + 1] | a[i];
for(int i = 1; i <= n; ++ i){
LL ret = a[i];
for(int j = 1; j <= k; ++ j) ret *= x;
Ans = max(Ans, ret | pre[i - 1] | bac[i + 1]);
}
printf("%lld
", Ans);
return 0;
}