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<iostream> #include<cstdio> #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<<ans<<endl; return 0; }