做法:位运算

思路:

确定攻击的每一位填1还是填0
填1必须满足:
该位为1了以后总和不能大于最大的攻击力
填1了之后运算过后答案的二进制位上还是1

其余情况填1也会变成0,否则就大于了m,还不如填0有效

代码

#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define mp(aa,bb) make_pair(aa,bb)
#define _for(i,b) for(int i=(0);i<(b);i++)
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define per(i,b,a) for(int i=(b);i>=(a);i--)
#define mst(abc,bca) memset(abc,bca,sizeof abc)
#define X first
#define Y second
#define lowbit(a) (a&(-a))
typedef long long ll;
typedef pair<int,int> pii;
typedef unsigned long long ull;
typedef long double ld;
const int N=1e5+10;
const int INF=0x3f3f3f3f;
const int mod=1e9+7;
const double eps=1e-6;
const double PI=acos(-1.0);

int n,m,ans;
string op[N];
int t[N];

bool calc(bool x,int j){
    for(int i=0;i<n;i++){
        if(op[i]=="OR") x|=t[i]>>j&1;
        else if(op[i]=="XOR") x^=t[i]>>j&1;
        else x&=t[i]>>j&1;
    }
    return x;
}

void solve(){
    cin>>n>>m;
    _for(i,n){
        cin>>op[i]>>t[i];
    }
    for(int i=29;~i;i--){
        if(m>>i){
            bool x=calc(0,i),y=calc(1,i);
            if(x>=y) ans|=x<<i;
            else ans|=y<<i,m-=1<<i;
        }
        else ans|=calc(0,i)<<i;
    }
    cout<<ans<<"\n";
} 


int main(){
    ios::sync_with_stdio(0);cin.tie(0);
#ifdef DEBUG
    freopen("F:/laji/1.in", "r", stdin);
//    freopen("F:/laji/2.out", "w", stdout);
#endif
//    int t;cin>>t;while(t--)
    solve();
    return 0;
}