起床困难综合症


title: 起床困难综合症
date: 2023-12-07 18:53:24
tags: 二进制状态压缩
categories: 算法竞赛

题目链接

− − > --> > 传送门

题目大意

d r d drd drd 的防御战线由 n n n 扇防御门组成。

每扇防御门包括一个运算 o p op op 和一个参数 t t t,其中运算一定是 O R , X O R , A N D OR,XOR,AND OR,XOR,AND 中的一种,参数则一定为非负整数。如果还未通过防御门时攻击力为 x x x,则其通过这扇防御门后攻击力将变为 x x x o p op op t t t

最终 d r d drd drd 受到的伤害为对方初始攻击力 x x x 依次经过所有 n n n 扇防御门后转变得到的攻击力。

由于 a t m atm atm 水平有限,他的初始攻击力只能为 0 0 0 m m m 之间的一个整数(即他的初始攻击力只能在 0 , 1 , … , m 0,1,…,m 0,1,,m 中任选,但在通过防御门之后的攻击力不受 m m m 的限制)。

为了节省体力,他希望通过选择合适的初始攻击力使得他的攻击能让 d r d drd drd 受到最大的伤害,请你帮他计算一下,他的一次攻击最多能使 d r d drd drd 受到多少伤害。

输入样例

3 3 3 10 10 10
A N D AND AND 5 5 5
O R OR OR 6 6 6
X O R XOR XOR 7 7 7

输出样例

1 1 1

思路

位运算的主要特点之一就是在二进制表示下不进位,因此,每一位是否为 1 1 1 是独立的。 a n s ans ans 的第 k k k 位只与 x o x_o xo 的第 k k k 位有关。

由此,我们从高位到低位依次考虑每一位填 1 1 1 还是 0 0 0

这相当于在 m m m 范围内造出一个符合条件的最大数字 a n s ans ans,这就要 a n s ans ans 的每一位尽可能的为 1 1 1。而满足填 1 1 1 的条件则是,已经填好更高位构成的数值加上当前第 k k k 位的 1 < < k 1 << k 1<<k 不超过 m m m,同时当前位置放 1 1 1 的贡献大于放 0 0 0

代码

#include<bits/stdc++.h>
using namespace std;

typedef long long LL;

const int N = 1e5 + 10;
 
pair<string,int> a[N];
int m,n;
int cal(int bit,int now)
{
	for(int i = 1; i <= n ; i ++){
		int x = a[i].second >> bit & 1;
		string str = a[i].first;
		if(str == "AND") now &= x;
		else if(str == "OR") now |= x;
		else now ^= x;
	}
	return now;
}
int main()
{
	
	cin >> n >> m;
	for(int i = 1;  i <= n; i ++){
		string s;int x;
		cin >> s >> x;
		a[i] = {s,x};
	}
	int val = 0,ans = 0;
	for(int i = 29; i >= 0 ; i --){
		int res1 = cal(i,1),res0 = cal(i,0);
		
		if(val + (1 << i) <= m && res0 < res1){
			ans += res1 << i,val += 1 << i;
		}
		else ans += res0 << i;
	}
	cout << ans << endl;
	return 0;
} 
  • 22
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值