首先,我们发现位运算和十进制的加减乘除不一样,位运算对于每一位都是独立的,而加减乘除会产生进位,在一位上的操作会影响另一位。
我们可以这样理解,对于一大堆不知道是蜃么奇奇怪怪的,, ,我们可以算出来一个函数(其中且),使得原数上位置的,经过操作之后对应位置上一定是。
考虑如何计算,发现只要搞一个全是的数和一个全是的数,按照题目意思给他操作一遍,操作完的数对应到位上,一定是和(因为位运算每一位都是独立的)
算出来就好做了,我们考虑贪心,
可以由变成,那么肯定要变
可以由变成,也要变
可以由变成,不用变(因为已经是最小的可能数了)
可以由变成,这样一搞反而亏本了,肯定不用变
详细细节见代码
#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);
}