题意:
选一个小于m的数,始得他经过一系列位运算后值最大。
题解:
因为数特别大,所以无法用暴力解决。
一开始想了贪心,不过只考虑了用111111111111这样的二进制过一遍然后检查得到的数,忘了可以用0过一遍了。
看了大佬的题解才恍然大悟,因为这题基础是位运算,所以我们我们把每一位拆开进行判断。
贪心这个想法是从,这个数要小于m得出的。
我们从最高位开始进行贪心,如果这个位一开始位0,经过这一些列位运算后,得出1,那么我们可以直接把答案的 这一位 变成0,因为贪心(尽可能让这个数不要超过m),如果经过这一些列位运算后,得出0,那么我们就需要康康 能不能 把答案的 这一位 变成1。因为答案要求这个数要小于m,如果这一位加上去之后,小于m,那么我们就可以把这一位 变为1,同时m减去这一位的大小。

代码:

/*Keep on going Never give up*/
//#pragma GCC optimize(3,"Ofast","inline")
#include<bits/stdc++.h>

#define int long long
#define endl '\n'
#define Accepted 0
#define AK main()
#define I_can signed
using namespace std;
const int maxn =1e5+10;
const int MaxN = 0x3f3f3f3f;
const int MinN = 0xc0c0c00c;
typedef long long ll;
const int inf=0x3f3f3f3f;
const ll mod=1e9+7;
using namespace std;

int x,y;
I_can AK
{
    ios::sync_with_stdio(false);
    int n,m;
    cin>>n>>m;
    y=-1;
    for(int i=0;i<n;i++){
        string s;
        int num;
        cin>>s>>num;
        if(s[0]=='A') x&= num,y&=num;
        else if(s[0]=='X') x^=num,y^=num;
        else x|=num,y|=num;
    }
    int ans=0;
    for(int i=1<<30;i;i>>=1){
        if(x&i) ans+=i;
        else if(y&i&&i<=m) ans+=i,m-=i;
        //cout<<11<<endl;
    }
    cout<<ans<<endl;
    return 0;
}