起床困难综合症[NOI2014]

【题解】

       并不算很困难的贪心题。位运算毕竟是针对每一位的,从前向后处理,如果某一位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;
}

 

posted @ 2017-07-26 20:07  moyiii  阅读(277)  评论(0编辑  收藏  举报