Codeforces Round #320 “Or“ Game 位运算 前缀和 暴力

题目链接

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;
	}


猜你喜欢

转载自blog.csdn.net/TheSunspot/article/details/109138880