【题解】 UOJ #2. 【NOI2014】起床困难综合症
不是很简单?
考虑一下这个数的二进制位是什么,要么是1,要么是0.
然后怎么做?
因为一开始可以选0~m的数,那么二进制为中全是0的肯定是可以选的。
接着考虑全是1的怎么选?
如果全都是1的而且比m要小,那么显然就可以选。
注意从大到小贪心的选(二进制为当前位往后面的和是一定不可能超过当前位的)。
#include<stdio.h>
#include<math.h>
#include<string.h>
using namespace std;
int a=2147483647,b=0,n,m,ans;
char s[5];
int main(){
int n,m;scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
int t;
scanf("%s%d",s,&t);
if(s[0]=='A'){a=a&t;b=b&t;}
if(s[0]=='O'){a=a|t;b=b|t;}
if(s[0]=='X'){a=a^t;b=b^t;}
}
for(int i=30;i>=0;i--)
if(b&(1<<i))ans+=1<<i;
else if(m>=(1<<i) && a&(1<<i))ans+=1<<i,m-=(1<<i);
printf("%d\n",ans);
return 0;
}