起床困难综合症
题目
题解
位运算一个很重要的性质,位与位之间不会互相影响。
我采用的做法是从大到小判断每一位取多少结果是\(1\)。
时间复杂度:\(O(nlogn)\)
对于每一位我们暴力代\(1\)或\(0\)进去,然后看结果是不是\(1\)就行了,如果都是\(1\)我们这一位优先取\(0\),给后面的点创造更多可以选择的空间。
代码
#include<cstdio>
#include<cstring>
#define N 110000
using namespace std;
struct node
{
int type,x;
}a[N];int n,m;
int ans=0;//答案
bool pd(int x,int k/*第k位是不是1*/)
{
for(int i=1;i<=n;i++)
{
if(a[i].type==1)x&=a[i].x;
else if(a[i].type==2)x|=a[i].x;
else x^=a[i].x;
}
return x&(1<<k);
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
char st[10];scanf("%s",st+1);
scanf("%d",&a[i].x);
if(st[1]=='A')a[i].type=1;
else if(st[1]=='O')a[i].type=2;
else a[i].type=3;
}
for(int i=30;i>=0;i--)
{
if(pd(0,i)==1)ans+=(1<<i);
else if((1<<i)<=m/*要判断数字是否在1-m范围内*/ && pd((1<<i),i)==1)ans+=(1<<i),m-=(1<<i);
}
printf("%d\n",ans);
return 0;
}