起床困难综合症[二进制运算]

题面

[https://www.luogu.com.cn/problem/P2114]

分析

题目要求是从[0,m]中选出一个数,经过给定的n次运算,得到结果ans最大
位运算主要特点之一是二进制表示下不进位
所以对于一个确定的x经过n次运算之后每一位的值是固定的
即每位上1或0最后的结果是可以确定的
那么预处理每一位0或1最后运算的结果之后
为了使ans最大,能变1都变1(但是要保证原来的数<=m)

code(换马蜂了)

#include <iostream>
#include <cstdio>
using namespace std;
inline int read(){
	register int x = 0, f = 1;
	register char c = getchar();
	while (c < '0' || c > '9') {if (c == '-') f = -1; c = getchar();}
	while (c >= '0' && c <= '9') x = (x << 3) + ( x << 1) + c - '0',c = getchar();
	return x * f;
}
int n, m;
int a0 = 0,a1 = -1;//-1在计算机中以补码形式存在,-1的补码为1111111……1
int init(){
	n = read(), m = read();
	while (n--){
		char str[5];
		scanf ("%s", str);
		int t = read();
		if (str[0] == 'A') a0 &= t, a1 &= t;
		if (str[0] == 'X') a0 ^= t, a1 ^= t;
		if (str[0] == 'O') a0 |= t, a1 |= t; 
	}
}

int doit(){
	int val=0,ans=0;
	for (int i = 29; i >= 0;i--){
		if (a0 >> i & 1) ans += 1 << i;//0能变1直接变
		else if (a1 >> i & 1 && (1 << i) + val <= m) ans += 1 <<i, val += (1 << i);//1能变1也直接变,同时考虑初始值的大小要小于m
	}
	printf ("%d", ans);
}

int main(){
	init();
	doit();
	return 0;
}

posted @   ancer  阅读(18)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
历史上的今天:
2019-09-20 luogu P1064 金明的预算方案
点击右上角即可分享
微信分享提示