关闭

"Or" Game

标签: 前缀和贪心
33人阅读 评论(0) 收藏 举报
分类:
链接:http://codeforces.com/problemset/problem/579/D

题目:

You are given n numbers a1, a2, ..., an. You can perform at most k operations. For each operation you can multiply one of the numbers by x. We want to make as large as possible, where denotes the bitwise OR.

Find the maximum possible value of after performing at most k operations optimally.



题意:给一串数,可以对任意数乘x,总共乘k次。为最后的全部异或和最大为多少

分析:基本是贪心,首先要求异或和最大,那么最好的情况是所有的k个x都乘到一起,因为这样数位最大,其次,保证低位的1尽可能的为奇数,但是却比较麻烦。查阅资料后发现一种另类的前缀和,这里可以叫做前缀异或和以及后缀异或和。输入后预处理一个前缀异或和和一个后缀异或和(均不包含自己),之后对每一个数求前缀和*自己*后缀和*k个x,比较得出最大值。


题解:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <string>
#include <cstring>
#include <functional>
#include <cmath>
#include <cctype>
#include <cfloat>
#include <climits>
#include <complex>
#include <deque>
#include <list>
#include <set>
#include <utility>
#define rt return 0
#define fr freopen("in.txt","r",stdin)
#define fw freopen("out.txt","w",stdout)
#define ll long long
using namespace std;

int a[200010];
int pre[200010];
int old[200010];

int main()
{
	int n, k, x;
	cin >> n >> k >> x;
	for (int i = 1; i <= n;i++)
	{
		cin >> a[i];
		pre[i] = pre[i - 1] | a[i];
	}
	for (int i = n; i > 0; i--)
		old[i] = old[i + 1] | a[i];
	ll l = 1, ans = 0;
	for (int i = 0; i < k; i++)
		l *= (ll)x;
	for (int i = 1; i <= n;i++)
	{
		ans = max(ans, (l*(ll)a[i]) | (ll)(pre[i - 1]) | (ll)(old[i + 1]));
	}
	cout << ans << endl;
	return 0;
}

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:3731次
    • 积分:597
    • 等级:
    • 排名:千里之外
    • 原创:59篇
    • 转载:0篇
    • 译文:0篇
    • 评论:0条
    友情链接