[NOI2014]起床困难综合症

这应该是$NOI2014$最简单的一题。

首先这题有$AND$、$OR$、$XOR$三个运算,跟二进制有关。

我们逐位看。

忽略$\leq m$的限制,在开始时每一位都可以是$0$或$1$,而不同的选择到最后的结果互不影响,所以共有四种组合。

想让结果更大,也就是想让结果尽可能多变成$1$。

加上$\leq m$的限制呢?

四种情况分别是:

(1)$0 \rightarrow 1 \ 1 \rightarrow 1$

(2)$0 \rightarrow 0 \ 1 \rightarrow 0$

(3)$0 \rightarrow 1 \ 1 \rightarrow 0$

(4)$0 \rightarrow 0 \ 1 \rightarrow 1$

前三种情况当然选择$0$,因为根据贪心即可保证结果最优,又可保证开始的数小。

第四种情况就要判断是否能选择$1$。如果选入了$1$使得开始的数$>m$,就不选。

正确性:从左往右,让结果为$1$,一定比从右往左选的结果更优,因为位数越靠左,数越大,优先选左边一定比右边要优。

 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 #define re register
 6 #define rep(i, a, b) for (re int i = a; i <= b; ++i)
 7 #define repd(i, a, b) for (re int i = a; i >= b; --i)
 8 #define maxx(a, b) a = max(a, b);
 9 #define minn(a, b) a = min(a, b);
10 #define LL long long
11 #define inf (1 << 30)
12 
13 inline int read() {
14     int w = 0, f = 1; char c = getchar();
15     while (!isdigit(c)) f = c == '-' ? -1 : f, c = getchar();
16     while (isdigit(c)) w = (w << 3) + (w << 1) + (c ^ '0'), c = getchar();
17     return w * f;
18 }
19 
20 const int maxn = 1e5 + 5;
21 
22 char opt[maxn][4];
23 
24 int bit[maxn][35], ans[maxn][2];
25 int n, m;
26 
27 int main() {
28     scanf("%d%d", &n, &m);
29     rep(i, 1, n) {
30         int v, L = 0;
31         scanf("%s %d", opt[i], &v);
32         while (v) {
33             bit[i][L++] = v & 1;
34             v >>= 1;
35         }
36     }
37 
38     rep(i, 0, 30) {
39         rep(tag, 0, 1) {
40             int x = tag;
41             rep(j, 1, n)
42                 if (opt[j][0] == 'A') x &= bit[j][i];
43                 else if (opt[j][0] == 'O') x |= bit[j][i];
44                 else x ^= bit[j][i];
45             ans[i][tag] = x ? 1 : 0;
46         }
47     }
48 
49     int res = 0, mx = 0;
50     repd(i, 30, 0) {
51         if (ans[i][0] == 0 && ans[i][1] == 1)
52             if (res + (1 << i) <= m) {
53                 res += 1 << i;
54                 mx += 1 << i;
55             }
56         if (ans[i][0] == 1 && ans[i][1] == 1 || ans[i][0] == 1 && ans[i][1] == 0) mx += 1 << i;
57     }
58     printf("%d", mx);
59     return 0;
60 }

 

posted @ 2019-02-02 16:04  AC-Evil  阅读(480)  评论(0编辑  收藏  举报