LOJ#2244. 「NOI2014」起床困难综合症
$n \leq 1e5$个位运算操作,$m \le 2^{30}$,问$0-m$中谁进行完所有操作值最大,输出这个最大值。
cfA题难度?当送分题就不管了
and相当于几个位取0,or相当于几个位取1,有几个位是可以确定的;xor相当于翻转,确定的0变1,确定的1变0,不确定的就记一下哪几位被xor了。最后从高到低按位决定这一位要不要填1,如果这一位没确定并且没被异或或者被异或了偶数次就填个1下去,否则不填。
1 //#include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 //#include<time.h> 5 //#include<math.h> 6 //#include<set> 7 //#include<queue> 8 //#include<bitset> 9 //#include<vector> 10 #include<algorithm> 11 #include<stdlib.h> 12 using namespace std; 13 14 #define LL long long 15 LL qread() 16 { 17 char c; LL s=0; int f=1; while ((c=getchar())<'0' || c>'9') (c=='-') && (f=-1); 18 do s=s*10+c-'0'; while ((c=getchar())>='0' && c<='9'); return s*f; 19 } 20 21 //Pay attention to '-' , LL and double of qread!!!! 22 23 int n,m,a,b,x,ba; 24 int main() 25 { 26 n=qread(); m=qread(); 27 a=ba=(1<<30)-1; b=x=0; 28 char c; int v; 29 while (n--) 30 { 31 while ((c=getchar())!='A' && c!='O' && c!='X'); 32 if (c=='A') 33 { 34 c=getchar(); c=getchar(); 35 v=qread(); a&=v; b&=v; x&=v; 36 } 37 else if (c=='O') 38 { 39 c=getchar(); 40 v=qread(); b|=v; a|=v; x&=ba^v; 41 } 42 else if (c=='X') 43 { 44 c=getchar(); c=getchar(); 45 v=qread(); 46 for (int i=0;i<30;i++) if ((v>>i)&1) 47 { 48 if (((b>>i)&1)==0 && ((a>>i)&1)==1) x^=1<<i; 49 else if ((b>>i)&1 || ((a>>i)&1)==0) a^=(1<<i),b^=(1<<i); 50 } 51 } 52 } 53 int tmp=0,ans=0; 54 for (int i=29;~i;i--) 55 { 56 if ((b>>i)&1) ans|=1<<i; 57 else if (((a>>i)&1)==0); 58 else 59 { 60 if ((x>>i)&1) ans|=1<<i; 61 else if ((tmp|(1<<i))<=m) tmp|=1<<i,ans|=1<<i; 62 } 63 } 64 printf("%d\n",ans); 65 return 0; 66 }