题意
你有次机会,可以选择是否对原数与进行与、或、异或三种操作之一(已指定),求最后的最大值是多少?
分析
因为位运算每一位之间是独立的,所以我们可以贪心的选择。
我们知道在二进制下数位越高代表的值越大,所以我们只需要从高位到低位贪心的是其尽可能的为。
做法
我用和两个变量表示二进制每一位全为和全为经过门之后的结果。贪心时,就能用换就一定换,能用换也换。对于,如果第位变成了,那么就得看原数的第位,如果是且它还在范围内,对最后的答案贡献为。
代码
#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; }