题目链接
http://codeforces.com/problemset/problem/578/B
题意
2e5数组,可对任意元素做*x的操作,最多k次,求处理后每个元素按位或的最大值
思路
首先可以证明,k次一定是对同一个数进行操作。
因为x大于2,所以操作后一定会让二进制串增大最少一位,假如不是全分配给一个,则一定可以重新分配成全分配给一个,最高位更大,答案更大的情况。
不能简单的对最大的数字做k次操作。比如100 110,x=2,k=1时,若对100做操作答案为1110,若对110做操作答案为1100.
考虑暴力,我们用特殊的前缀和优化,pr维护按位或的前缀和,ta维护按位或的后缀和,这样可以O(1)的处理每个元素k次操作的情况,遍历每一个元素,记录答案即可,时间复杂度O(n)
代码
#include<cstdio>
#include<iostream>
#include<iomanip>
#include<map>
#include<string>
#include<queue>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define endl "\n"
#define int long long
//#define double long double
using namespace std;
typedef long long ll;
const int maxn=200500;
const int inf=0x3f3f3f3f;
int n,k,x;
int a[maxn];
int pr[maxn],ta[maxn];
signed main(){
IOS
cin>>n>>k>>x;
for(int i=1;i<=n;i++)
cin>>a[i];
a[0]=a[n+1]=0;
for(int i=1;i<=n;i++){
pr[i]=a[i]|pr[i-1];
}
for(int i=n;i>=1;i--){
ta[i]=a[i]|ta[i+1];
}
int p=1;
while(k--){
p*=x;
}
int ans=-inf;
for(int i=1;i<=n;i++){
int t=pr[i-1]|(a[i]*p)|ta[i+1];
ans=max(ans,t);
}
cout<<ans<<endl;
}