题意

你有次机会,可以选择是否对原数与进行与、或、异或三种操作之一(已指定),求最后的最大值是多少?

分析

因为位运算每一位之间是独立的,所以我们可以贪心的选择。
我们知道在二进制下数位越高代表的值越大,所以我们只需要从高位到低位贪心的是其尽可能的为

做法

我用两个变量表示二进制每一位全为和全为经过门之后的结果。贪心时,就能用就一定换,能用也换。对于,如果第位变成了,那么就得看原数的第位,如果是且它还在范围内,对最后的答案贡献为

代码

#include<bits/stdc++.h>
#define ll long long
const int N=1e5+5,INF=0x3f3f3f3f,mod=998244353;
using namespace std;

int n,m,a1=0,a2=-1,ans;
char opt[N];

inline int read()
{
    register int x=0,f=1;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1;c=getchar();}
    while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar();
    return x*f;
}

int qpow(int a,int b)
{
    int ans=1;
    while(b){if(b&1) ans=ans*a%mod;a=a*a%mod;b>>=1;}
    return ans;
}

int main()
{
    n=read();m=read();
    for(int i=1;i<=n;i++)
    {
        scanf("%s",opt);
        int d=read();
        if(opt[0]=='A')a1&=d,a2&=d;
        if(opt[0]=='O')a1|=d,a2|=d;
        if(opt[0]=='X')a1^=d,a2^=d;
    }
    for(int j=29;~j;--j)
    {
        if(a1>>j&1) ans+=1<<j;
        else if(a2>>j&1&&(1<<j)<=m) ans+=1<<j, m-=1<<j;
    } 
    printf("%d",ans);
    return 0;
}