题意: 给定个操作和数,问当初值在时,按照个操作的顺序操作后可以获得的最大值。
数据范围:,操作只有或运算,与运算和异或运算三种。

题解:
位运算每位独立,故可以单独考虑每位。

  • 由于二进制每位只有两种取值,故可以考虑每位初值为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;
}