题意: 给定个操作和数,问当初值在时,按照个操作的顺序操作后可以获得的最大值。
数据范围:,操作只有或运算,与运算和异或运算三种。
题解:
位运算每位独立,故可以单独考虑每位。
- 由于二进制每位只有两种取值,故可以考虑每位初值为0和1的情况。那么对应的十进制初值只需要用两个数:和不小于的梅森数即可,对应二进制位即全和全。
- 在对和进行组操作后,记操作后的数为和。
- 优先处理二进制高位,保证答案最大。同时在取可以为的位时,优先取由转移过来的。当考虑转移过来的位时,保证此时的位十进制大小加上之前的大小和不大于
代码:
#include<bits/stdc++.h> using namespace std; int main() { int n, m; scanf("%d%d", &n, &m); int a0 = 0, a1 = -1; for(int i = 1; i <= n; ++i) { char op[10]; int x; scanf("%s%d", op, &x); if(*op == 'A') a0 &= x, a1 &= x; else if(*op == 'X') a0 ^= x, a1 ^= x; else a0 |= x, a1 |= x; } int sum = 0; for(int i = 1 << 29; i >= 1; i >>= 1) { if(a0 & i) sum |= i; else if((a1 & i) && i <= m) sum |= i, m -= i; } printf("%d\n", sum); return 0; }