【题解】
并不算很困难的贪心题。位运算毕竟是针对每一位的,从前向后处理,如果某一位1比0更优且可取1就使它为1。比较0和1的结果要单取这一位来看,但是题目中所给的参数并没有必要全部二进制分解,直接用十进制得到的答案是一样的。预处理出2的前29次方(几乎是正好卡到10^9),取二进制位就变得更简单了。
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int ef[30],n,m,cs[100010],temp,tp,jg,wf; char a[100010][5]; int main() { //freopen("t.txt","r",stdin); freopen("sleep.in","r",stdin); freopen("sleep.out","w",stdout); ef[0]=1; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%s%d",a[i],&cs[i]); temp=0; for(int i=1;i<=29;i++) { ef[i]=ef[i-1]<<1; if(ef[i]<=m) temp=i; } for(int i=temp+1;i>=0;i--) { if(jg+ef[i]>m) continue; tp=ef[i]; for(int j=1;j<=n;j++) { if(a[j][0]=='X') tp^=cs[j]; if(a[j][0]=='A') tp&=cs[j]; if(a[j][0]=='O') tp|=cs[j]; } wf=0; for(int j=1;j<=n;j++) { if(a[j][0]=='X') wf^=cs[j]; if(a[j][0]=='A') wf&=cs[j]; if(a[j][0]=='O') wf|=cs[j]; } if((wf&ef[i])<(tp&ef[i])) jg+=ef[i]; } for(int i=1;i<=n;i++) { if(a[i][0]=='X') jg^=cs[i]; if(a[i][0]=='A') jg&=cs[i]; if(a[i][0]=='O') jg|=cs[i]; } printf("%d",jg); //while(1); return 0; }