传送门

首先,我们发现位运算和十进制的加减乘除不一样,位运算对于每一位都是独立的,而加减乘除会产生进位,在一位上的操作会影响另一位。

我们可以这样理解,对于一大堆不知道是蜃么奇奇怪怪的AndAndOrOrXorXor ,我们可以算出来一个函数f(x,pos)f(x,pos)(其中x=0,1x=0,1f(x,pos)=0,1f(x,pos)=0,1),使得原数上pospos位置的xx,经过操作之后对应位置上一定是f(x)f(x)

考虑如何计算f(x)f(x),发现只要搞一个全是11的数和一个全是00的数,按照题目意思给他操作一遍,操作完的数对应到pospos位上,一定是f(1,pos)f(1,pos)f(0,pos)f(0,pos)(因为位运算每一位都是独立的)

算出来f(x)f(x)就好做了,我们考虑贪心,

可以由00变成11,那么肯定要变

可以由11变成11,也要变

可以由00变成00,不用变(因为00已经是最小的可能数了)

可以由11变成00,这样一搞反而亏本了,肯定不用变

详细细节见代码

#include <bits/stdc++.h>
#define MAXM 30
using namespace std;
inline int read(){
    int x=0,f=1;
    char ch=getchar();
    while (ch<'0'||ch>'9'){
        if (ch=='-') f=-1;
        ch=getchar(); 
    }
    while (ch>='0'&&ch<='9'){
        x=(x<<3)+(x<<1)+(ch^'0');
        ch=getchar();
    }
    return x*f;
}
inline char gc(){
    char ch=getchar();
    while (ch!='A'&&ch!='O'&&ch!='X') ch=getchar();
    return ch;
}
int main(){
    int n=read(),m=read();
    int f1=0x7fffffff,f0=0;
    for (register int i=1;i<=n;++i){
        char opr=gc();
        int x=read();
        if (opr=='A') f0&=x,f1&=x;
        if (opr=='O') f0|=x,f1|=x;
        if (opr=='X') f0^=x,f1^=x;
    }
    int ans=0;
    for (register int i=MAXM;i>=0;--i){
        if (f0&(1<<i)){
            ans|=(1<<i);
        }
        else if ((1<<i)<=m&&(f1&(1<<i))){
            ans|=(1<<i);
            m-=(1<<i);
        }
    }
    printf("%d\n",ans);
}