【Luogu】2114起床困难综合征(位运算贪心)
这题真是恶心死我了。
由于位运算每一位互不干涉,所以贪心由大到小选择每一位最优的解,但是要判断一下边界,如果选择该解使得原数>m则不能选择。
代码如下
#include<cstdio> #include<cstring> #include<cctype> inline long long read(){ long long num=0,f=1; char ch=getchar(); while(!isdigit(ch)){ if(ch=='-') f=-1; ch=getchar(); } while(isdigit(ch)){ num=num*10+ch-'0'; ch=getchar(); } return num*f; } struct defend{ char c[10]; long long opt; }que[300010]; long long cnt; long long ans; int main(){ long long n=read(),m=read(); for(int i=1;i<=n;++i) scanf("%s%lld",que[i].c+1,&que[i].opt); for(long long i=34;i>=0;--i){ if(ans+((long long)1<<i)>m) continue; long long s=ans,x=ans+(1<<i); for(int j=1;j<=n;++j){ char ch=que[j].c[1]; long long opt=que[j].opt; if(ch=='A'){ s&=opt; x&=opt; } else if(ch=='O'){ s|=opt; x|=opt; } else if(ch=='X'){ s^=opt; x^=opt; } } s=s&(1<<i); x=x&(1<<i); if(s<x) ans+=1<<i; } for(int j=1;j<=n;++j){ char ch=que[j].c[1]; long long opt=que[j].opt; if(ch=='A'){ ans&=opt; } else if(ch=='O'){ ans|=opt; } else if(ch=='X'){ ans^=opt; } } printf("%lld",ans); return 0; }