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\n",t); b[0]=0;b[1]=1; for(int i=1;i<=n;i++) { // printf("op[%d]=%d s[%d][%d]=%d\n",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\n",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; }