本题就是让我们选一个([0,m])之间的数字,让这个数字经过n次位运算后最大。
位运算的特点就是在二进制位表示下不进位,因此,对于我们选定的数字x,我们可以枚举它这个位是1还是0,每个位的运算是两两不影响的。因此我们可以贪心的从高位往低位枚举,来判断。
对于x的第i位,要选1还是选0可以这样判断
1.已经填好的数字加上这个位的值(1<<i)不超过m
2.让第i位为0,和为1分别去计算,来判断哪个更优。
my code:
#include<iostream>
#include<cstdio>
#define rep(i,j,k) for(register int i(j);i<=k;++i)
#define drp(i,j,k) for(register int i(j);i>=k;--i)
#define bug puts(~~~~~~~);
#define bugout(x) cout<<x<<endl;
using namespace std;
typedef long long lxl;
template<typename T>
inline T max(T &a, T &b) {
return a > b ? a : b;
}
template<typename T>
inline T min(T &a, T &b) {
return a < b ? a : b;
}
const int N=1e5+79;
int n, m;
#define int long long
char ch[N][5];
int a[N];
inline int calc(int bit,int x){
rep(i,1,n){
int t=(a[i]>>bit)&1;
if(ch[i][0]=='A') x&=t;
else if(ch[i][0]=='O') x|=t;
else x^=t;
}
return x;
}
main() {
ios::sync_with_stdio(false);
cin>>n>>m;
rep(i,1,n){
cin>>ch[i];
cin>>a[i];
}
int val(0),ans(0);
drp(i,29,0){
int r0=calc(i,0);
int r1=calc(i,1);
if(val+(1<<i)<=m&&r0<r1){
val+=(1<<i);
ans+=r1<<i;
}
else ans+=r0<<i;
}
cout<<ans<<'
';
return 0;
}