起床困难综合症
原题链接
题目描述
在\([0, m]\)中找一个数,在经过\(n\)次位运算之后得到的值最大,求这个最大的值。
输入样例
3 10
AND 5
OR 6
XOR 7
输出样例
1
思路
首先,我们知道位运算是不存在进位的,所以一个位置上填1或0与其他的位置是无关的。
有了以上的结论,我们可以把问题简化成枚举一个数它的每一位是否可以填1
如果一个位置上可以填1,这个位置必须满足以下两个条件:
1.填上1之后,这个数不会超过m
2.填上1之后,经过n次位运算,结果比填上0要大,假如填上0和填上1相同,我们必然要优先填0。
因为填上0下面的位置更有可能填1而不超过m。
代码实现
#include <iostream>
using namespace std;
const int N = 1e5 + 10;
pair<string, int> a[N];
int n, m;
int calc(int bit, int now){
for(int i = 0; i < n; i++){
int x = a[i].second >> bit & 1;
if(a[i].first == "AND") now &= x;
if(a[i].first == "OR") now |= x;
if(a[i].first == "XOR") now ^= x;
}
return now;
}
int main(){
cin >> n >> m;
for(int i = 0; i < n; i++) cin >> a[i].first >> a[i].second;
int ans = 0, val = 0;
for(int bit = 29; bit >= 0; bit--){
int res0 = calc(bit, 0);
int res1 = calc(bit, 1);
if(val + (1 << bit) <= m && res0 < res1)
val += 1 << bit, ans += 1 << bit;
else ans += res0 << bit;
}
cout << ans << endl;
return 0;
}