文章目录
  1. 1. 输入格式
  2. 2. 输出格式
  3. 3. 样例一
    1. 3.1. input
    2. 3.2. output
    3. 3.3. explanation
  4. 4. 样例二
  5. 5. 限制与约定
  6. 6. codes

如果你看到的数学公式比较奇怪,请调整浏览器的https安全设置

21 世纪,许多人得了一种奇怪的病:起床困难综合症,其临床表现为:起床难,起床后精神不佳。作为一名青春阳光好少年,atm 一直坚持与起床困难综合症作斗争。通过研究相关文献,他找到了该病的发病原因:在深邃的太平洋海底中,出现了一条名为 drd 的巨龙,它掌握着睡眠之精髓,能随意延长大家的睡眠时间。正是由于 drd 的活动,起床困难综合症愈演愈烈,以惊人的速度在世界上传播。为了彻底消灭这种病,atm 决定前往海底,消灭这条恶龙。

历经千辛万苦,atm 终于来到了 drd 所在的地方,准备与其展开艰苦卓绝的战斗。drd 有着十分特殊的技能,他的防御战线能够使用一定的运算来改变他受到的伤害。具体说来,drd 的防御战线由 $n$ 扇防御门组成。每扇防御门包括一个运算 $op$ 和一个参数 $t$,其中运算一定是 $\texttt{OR}, \texttt{XOR}, \texttt{AND}$ 中的一种,参数则一定为非负整数。如果还未通过防御门时攻击力为 $x$,则其通过这扇防御门后攻击力将变为 $x~op~t$。最终drd 受到的伤害为对方初始攻击力 $x$ 依次经过所有 $n$ 扇防御门后转变得到的攻击力。

由于 atm 水平有限,他的初始攻击力只能为 $0$ 到 $m$ 之间的一个整数(即他的初始攻击力只能在 $0,1,\dots,m$ 中任选,但在通过防御门之后的攻击力不受 $m$ 的限制)。为了节省体力,他希望通过选择合适的初始攻击力使得他的攻击能让 drd 受到最大的伤害,请你帮他计算一下,他的一次攻击最多能使 drd 受到多少伤害。

输入格式

第一行包含两个整数,依次为 $n,m$,表示 drd 有 $n$ 扇防御门,atm 的初始攻击力为 $0$ 到 $m$ 之间的整数。

接下来 $n$ 行,依次表示每一扇防御门。每行包括一个字符串 $op$ 和一个非负整数 $t$,两者由一个空格隔开,且 $op$ 在前,$t$ 在后,$op$ 表示该防御门所对应的操作,$t$ 表示对应的参数。

输出格式

一行一个整数,表示 atm 的一次攻击最多使 drd 受到多少伤害。

样例一

input

3 10
AND 5
OR 6
XOR 7

output

1

explanation

atm可以选择的初始攻击力为 $0, 1, \dots, 10$。

假设初始攻击力为$4$,最终攻击力经过了如下计算
\begin{eqnarray}
4~\texttt{AND}~5 & = & 4\
4~\texttt{OR}~6 & = & 6\
6~\texttt{XOR}~7 & = & 1\
\end{eqnarray}
类似的,我们可以计算出初始攻击力为 $1,3,5,7,9$ 时最终攻击力为 $0$,初始攻击力为 $0,2,4,6,8,10$ 时最终攻击力为 $1$,因此 atm 的一次攻击最多使 drd 受到的伤害值为 $1$。

样例二

见“样例数据下载”

限制与约定

所有测试数据的范围和特点如下表所示

测试点编号$n, m$的规模约定备注
1$2 \leq n \leq 100, m = 0$$0 \leq t < 2^{30}$
$op$一定为$\texttt{OR}, \texttt{XOR}, \texttt{AND}$中的一种
2$2 \leq n \leq 1000, 1 \leq m \leq 1000$
3
4$2 \leq n, m \leq 10^5$存在一扇防御门为$\texttt{AND}~0$
5所有防御门的操作均相同
6
7$2 \leq n \leq 10^5, 2 \leq m < 2^{30}$所有防御门的操作均相同
8
9
10

在本题中,选手需要先将数字变换为二进制后再进行计算。如果操作的两个数二进制长度不同,则在前补 $0$ 至相同长度。

$\texttt{OR}$ 为按位或运算,处理两个长度相同的二进制数,两个相应的二进制位中只要有一个为 $1$,则该位的结果值为 $1$,否则为 $0$。

$\texttt{XOR}$ 为按位异或运算,对等长二进制模式或二进制数的每一位执行逻辑异或操作。如果两个相应的二进制位不同(相异),则该位的结果值为 $1$,否则该位为 $0$。

$\texttt{AND}$ 为按位与运算,处理两个长度相同的二进制数,两个相应的二进制位都为 $1$,该位的结果值才为 $1$,否则为 $0$。

例如,我们将十进制数 $5$ 与十进制数 $3$ 分别进行 $\texttt{OR}$,$\texttt{XOR}$ 与 $\texttt{AND}$ 运算,可以得到如下结果:

    0101 (十进制 5)
 OR 0011 (十进制 3)
  = 0111 (十进制 7)
    0101 (十进制 5)
XOR 0011 (十进制 3)
  = 0110 (十进制 6)
    0101 (十进制 5)
AND 0011 (十进制 3)
  = 0001 (十进制 1)

时间限制:$1\texttt{s}$
空间限制:$512\texttt{MB}$

codes

第一次写NOI题目,调了几乎一天,好多实现的细节问题。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=100010;
int n, m;
int ope[maxn], t[maxn];
char str[5];
int tt, len=31;
int num[2][40], mm[40];
int flag=0;
int ans=0;
int main()
{
scanf("%d %d", &n, &m);
for(int i=0; i<n; i++)
{
scanf("%s %d", str, &t[i]);
if(str[0]=='A')
ope[i]=1;
else if(str[0]=='O')
ope[i]=2;
else if(str[0]=='X')
ope[i]=3;
}
tt=m;
for(int i=0; i<len; i++, tt>>=1)
mm[i]=(tt & 1);
tt=0;
for(int i=0; i<n; i++)
if(ope[i]==1)
tt=(tt & t[i]);
else if(ope[i]==2)
tt=(tt | t[i]);
else if(ope[i]==3)
tt=(tt ^ t[i]);
for(int i=0; i<len; i++, tt>>=1)
num[0][i]=(tt & 1);
tt=(2<<len)-1;
for(int i=0; i<n; i++)
if(ope[i]==1)
tt=(tt & t[i]);
else if(ope[i]==2)
tt=(tt | t[i]);
else if(ope[i]==3)
tt=(tt ^ t[i]);
for(int i=0; i<len; i++, tt>>=1)
num[1][i]=(tt & 1);
for(int i=len-1; i>=0; i--)
{
if(flag)
{
ans=((ans<<1) | (num[0][i] | num[1][i]));
}
else if(mm[i])
{
if(num[0][i])
{
flag=1;
ans=((ans<<1) | 1);
}
else if(num[1][i])
ans=((ans<<1) | 1);
else
{
ans=(ans<<1);
flag=1;
}
}
else
ans=((ans<<1) | num[0][i]);
}
printf("%d\n", ans);
return 0;
}

文章目录
  1. 1. 输入格式
  2. 2. 输出格式
  3. 3. 样例一
    1. 3.1. input
    2. 3.2. output
    3. 3.3. explanation
  4. 4. 样例二
  5. 5. 限制与约定
  6. 6. codes