bzoj3668[Noi2014]起床困难综合症

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3668

这种题目就要按位考虑!!!

lm不是m的最高位,而是m和各个参数的最高位。因为可能sum的那一位是0而能是答案是1。

(时间是平均水平两倍的代码如下……)

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=1e5+5,LM=31;
int n,m,lm,op[N],s[N][LM+5],sum,ans,b[2];
void init()
{
    int k=m,cnt=0;while(k)k>>=1,cnt++;lm=max(lm,cnt);
}
void solve(int i,int k)
{
    for(int j=1;j<=LM;j++)
    {
        if(k&1)s[i][j]=1;k>>=1;
        if(!k){lm=max(lm,j);break;}
    }
}
int main()
{
    scanf("%d%d",&n,&m);init();
    char ch[5];int tp;
    for(int i=1;i<=n;i++)
    {
        scanf("%s",ch);scanf("%d",&tp);solve(i,tp);
        if(ch[0]=='A')op[i]=1;if(ch[0]=='O')op[i]=2;if(ch[0]=='X')op[i]=3;
    }
    for(int t=lm;t;t--)
    {
//        printf("t=%d
",t);
        b[0]=0;b[1]=1;
        for(int i=1;i<=n;i++)
        {
//            printf("op[%d]=%d s[%d][%d]=%d
",i,op[i],i,t,s[i][t]);
            if(op[i]==1&&s[i][t]==0)b[0]=0,b[1]=0;
            else if(op[i]==2&&s[i][t]==1)b[0]=1,b[1]=1;
            else if(op[i]==3)b[0]^=s[i][t],b[1]^=s[i][t];
        }
//        printf("b[0]=%d b[1]=%d
",b[0],b[1]);
        if(b[0])ans|=(1<<(t-1));
        else if(b[1]&&(sum|(1<<(t-1)))<=m)sum|=(1<<(t-1)),ans|=(1<<(t-1));
    }
    printf("%d",ans);
    return 0;
}
原文地址:https://www.cnblogs.com/Narh/p/9167631.html