#P14936. [uoi2019]Atlas机器人

[uoi2019]Atlas机器人

题目描述

众所周知,哥萨克·乌斯有一个他童年时非常喜欢的机器人 Atlas。今天乌斯发现,自己从来没有试着把这个机器人编程去完成别的事情,于是他开始阅读说明书。

说明书中写道:Atlas 的内存中保存着 4040 个从 11 开始编号的寄存器,每个寄存器包含 6464 个二进制位。因此,每个寄存器都由 64640011 组成。

乌斯还发现,可以使用下面 77 种命令对寄存器进行操作。为了方便,称编号为 ii 的寄存器为寄存器 ii,并记 aia_i 为寄存器 ii 中存储的无符号整数。

  1. setValue(i, j):将寄存器 ii 替换为寄存器 jj,即 ai=aja_i=a_j
  2. setXor(i, j, k):将寄存器 ii 替换为寄存器 jj 与寄存器 kk 的按位 xor,即 ai=ajxoraka_i=a_j\operatorname{xor}a_k
  3. setAnd(i, j, k):将寄存器 ii 替换为寄存器 jj 与寄存器 kk 的按位 and,即 ai=ajandaka_i=a_j\operatorname{and}a_k
  4. setOr(i, j, k):将寄存器 ii 替换为寄存器 jj 与寄存器 kk 的按位 or,即 ai=ajoraka_i=a_j\operatorname{or}a_k
  5. shiftLeft(i, x):将寄存器 ii 的所有二进制位向左移动 xx 位。
  6. shiftRight(i, x):将寄存器 ii 的所有二进制位向右移动 xx 位。
  7. setNot(i, j):将寄存器 ii 替换为寄存器 jj 的按位取反。也就是说,如果寄存器 jj 某一位为 00,则寄存器 ii 的对应位为 11;反之为 00

两个二进制位执行 xor 的结果是:若两位相同,结果为 00;若两位不同,结果为 11

两个二进制位执行 and 的结果是:仅当两位都为 11 时,结果为 11;否则为 00

两个二进制位执行 or 的结果是:仅当两位都为 00 时,结果为 00;否则为 11

寄存器向左移动 xx 位后,新寄存器的每一位等于原寄存器中向右数 xx 位处的那一位;如果原寄存器中不存在这样的位置,则这一位为 00

寄存器向右移动 xx 位后,新寄存器的每一位等于原寄存器中向左数 xx 位处的那一位;如果原寄存器中不存在这样的位置,则这一位为 00

读完说明书后,哥萨克·乌斯立刻想出了 66 个有趣的任务。对于每个任务,你需要给机器人输入一串命令,使得机器人完成对应任务。

设你在某个任务中执行的命令数为 tt

任务列表与评分

子任务 1:判断偶数,最高 66

寄存器 11 中写有数 xx。所有其他寄存器初始时均为 00

y=1y=1 表示 xx 为偶数,令 y=0y=0 表示 xx 为奇数。你的目标是:执行命令后,使寄存器 22 中写有 yy

得分为:

6tmin(3,t)3\left\lfloor 6-\sqrt[3]{t-\min(3,t)}\right\rfloor

子任务 2:加法,最高 1010

寄存器 11 中写有 xx,寄存器 22 中写有 yy。所有其他寄存器初始时均为 00

z=x+yz=x+y。你的目标是:执行命令后,使寄存器 33 中写有 zz

如果 zz 的二进制表示需要超过 6464 位,则寄存器 33 中只保留低 6464 位,也就是结果按 2642^{64} 取模。

得分为:

$$\left\lfloor 10-\sqrt[3]{t-\min(260,t)}\right\rfloor$$

子任务 3:统计二进制中 11 的个数,最高 1313

寄存器 11 中写有数 xx

yyxx 的二进制表示中 11 的个数。你的目标是:执行命令后,使寄存器 22 中写有 yy

本 Hydro 配置中的评测器按如下公式给分:

$$\left\lfloor 13-\frac{\ln(t-\min(1505,t)+1)}{1.2}\right\rfloor$$

子任务 4:比较大小,最高 2323

寄存器 11 与寄存器 22 中分别写有两个不同的数 xxyy

你的目标是:执行命令后,使:

  • 寄存器 33 中写有 [x>y][x>y]
  • 寄存器 44 中写有 [y>x][y>x]

其中 [P][P] 表示:若命题 PP 为真,则值为 11;否则值为 00

得分为:

$$\left\lfloor 23-\sqrt[2.5]{t-\min(92,t)}\right\rfloor$$

子任务 5:构造 2y12^y-1,最高 1818

寄存器 11 中写有数 xx

yyxx 的二进制表示中 11 的个数。你的目标是:执行命令后,使寄存器 11 中写有 2y12^y-1

得分为:

$$\left\lfloor 18-\sqrt[4]{t-\min(6560,t)}\right\rfloor$$

子任务 6:排序 99 个数,最高 3030

aa 是一个包含 99 个非负整数的数组,且这 99 个整数两两不同。初始时,对于 1i91\le i\le 9,寄存器 ii 中写有 aia_i

bb 为将数组 aa 按升序排序后的数组。你的目标是:执行命令后,对于每个 1i91\le i\le 9,寄存器 ii 中写有 bib_i

数组 aabb 均从 11 开始编号。

得分为:

$$\left\lfloor 30-\sqrt[3]{t-\min(4644,t)}\right\rfloor$$

额外说明

如果没有特别说明某个寄存器的初始值,则它初始时全部由 00 组成。

所有数都在 0026412^{64}-1 之间。寄存器中的运算均按 6464 位无符号整数进行。

你需要找到一串命令,使其对于该子任务的任意合法初始数据都正确。

你最多可以输出 10510^5 条命令。若命令数超过 10510^5,将被判为错误。若输出了非法命令或非法参数,也会被判为错误。

本题只检查任务要求的结果寄存器,其他寄存器中可以是任意数。

Hydro 版输入格式

本题在 Hydro 中配置为普通输入输出题,但使用 Special Judge 模拟机器人命令。

输入文件第一行包含两个整数:

G T

其中 GG 表示当前测试点对应的子任务编号,1G61\le G\le 6TT 是评测器使用的测试组数。

随后若干行是评测器用于验证命令正确性的隐藏数据。你的程序可以只读取 GG,忽略其余输入。

Hydro 版输出格式

第一行输出一个整数 tt,表示命令条数。

接下来输出 tt 行,每行表示一条命令。为了适配普通输出格式,七种命令用数字编码:

编号 输出格式 对应命令
1 1 i j setValue(i, j)
2 2 i j k setXor(i, j, k)
3 3 i j k setAnd(i, j, k)
4 4 i j k setOr(i, j, k)
5 5 i x shiftLeft(i, x)
6 6 i x shiftRight(i, x)
7 7 i j setNot(i, j)

参数限制如下:

  • 寄存器编号必须满足 1i,j,k401\le i,j,k\le 40
  • 位移量必须满足 0x640\le x\le 64

输出中不需要加入原包中的密码行。本 Hydro 配置已经将原始 checker 的密码要求去掉。

说明样例

假设寄存器 11 中写有 66,寄存器 22 中写有 33。如果执行如下命令:

setValue(3, 1)
setXor(4, 1, 2)
setAnd(5, 1, 2)
setOr(6, 2, 1)
shiftLeft(2, 3)
shiftRight(1, 2)
setNot(7, 2)

则前七个寄存器中的数会变成:

[1, 24, 6, 5, 2, 7, 18446744073709551591].[1,\ 24,\ 6,\ 5,\ 2,\ 7,\ 18446744073709551591].

若按 Hydro 输出格式写,上述命令序列应写作:

7
1 3 1
2 4 1 2
3 5 1 2
4 6 2 1
5 2 3
6 1 2
7 7 2

兼容说明:原官方评测格式在输出最后需要一行固定密码 958299301。本 Hydro 版本不要求输出该密码;若使用旧模板额外输出该行,特判也会兼容接受。