uoj#P646. 【美团杯2021】J. 随机数
【美团杯2021】J. 随机数
这是一道交互题
蒜斜有一个神秘的随机数生成器 $A$。其工作原理如下:
$A$ 中有 $100$ 个类型为 unsigned long long 的变量,编号为 $0 \sim 99$。这其中编号 $0 \sim m-1$ 的变量与生成的随机数有关。
每一次初始化 $A$ 的时候,$A$ 都会独立随机的生成一段代码来生成随机数,代码规则如下:
- 编号为 $0 \sim m-1$ 的变量为特殊变量,他们的值在一轮随机过程后不会被清空。其余变量的值会被清零。
- 一轮程序由不超过 $10^4$ 条赋值语句组成和恰好一条返回语句组成,赋值语句种类如下:
- $a = b\ \mathrm{xor}\ c$,其中 $a$ 为一变量,$b,c$ 为一$[0,2^{64})$整数常数或者变量
- $a = b\ \mathrm{<<}\ c$,其中 $a$ 为一变量,$\mathrm{<<}$ 为二进制左移操作,$b$ 为一$[0,2^{64})$整数常数或者变量, $c$ 为一个 $0 \sim 63$ 的整数常数
- $a = b\ \mathrm{>>}\ c$,其中 $a$ 为一变量,$\mathrm{>>}$ 为二进制右移操作,$b$ 为一$[0,2^{64})$整数常数或者变量, $c$ 为一个 $0 \sim 63$ 的整数常数
- $a = b\ \mathrm{and}\ c$,其中 $a$ 为一变量,$b$ 为一$[0,2^{64})$整数常数或者变量, $c$ 为一$[0,2^{64})$整数常数
- $a = b\ \mathrm{or}\ c$,其中 $a$ 为一变量,$b$ 为一$[0,2^{64})$整数常数或者变量, $c$ 为一$[0,2^{64})$整数常数
- 这里保证,如果在某一次运算中出现了编号为 $m \sim 99$ 的变量,则其要不为被赋值对象 $a$,要不在先前的计算中已经被赋值。
- 返回语句形如 $\mathrm{return}\ a$,其中 $a$ 为一变量,其作为这一轮程序运行后生成的随机数的值。蒜斜保证这一条返回语句是每一轮程序运行时候最后一个语句。且返回的变量 $a$ 满足其编号小于 $m$ 或者 $a$ 在执行时进行过至少一次赋值操作。
- 程序初始化时蒜斜会手动设定变量 $0 \sim m-1$ 的值。
- 蒜斜保证生成每一轮执行的代码片段完全相同。
蒜斜给他的程序加了密,于是任何人无法访问这个随机数生成器中生成的任何中间变量的值,也不知道蒜斜设定的 $m$ 个初始值,以及蒜斜随机数生成器的程序。蒜斜觉得他的程序可以输出一个超级随机的序列,这个序列无法被预知。
你是一名大预言家,你打算采用一些奇怪的占星术,预言蒜斜的程序在若干轮后的输出结果。
交互格式
本题只支持 c++
。
你需要包含头文件 interactor.h
。
你不需要,也不应该实现主函数,你只需要实现如下两个函数:
void solve(int m)
:- 你可以在这个函数内调用若干次蒜斜的随机数生成器 $A$。
- 参数 $m$ 含义如题面所示。
- 这个函数没有返回值。
unsigned long long query(int x)
:- 蒜斜在已经结束的所有操作的基础上,又执行了恰好 $x$ 次随机数生成器 $A$.
- 你需要返回最后一次调用操作后,随机数生成器返回的结果。
- 蒜斜 保证 $1 \le x \le 10^9$
你可以通过如下函数调用蒜斜的随机数生成器
unsigned long long random_ull()
:- 蒜斜 执行了恰好 $1$ 次随机数生成器 $A$.
- 返回这一次操作后随机数生成器返回的结果。
- 注意在执行
query
时你无法调用该操作。也就是说,这个操作仅能在执行solve
时执行。
由于蒜斜的耐心有限,你至多只能调用 $K$ 次 蒜斜 的随机数生成器。也就是说你至多只能调用 $K$ 次 random_ull
,且仅仅能在 solve
中调用。
本题保证所使用的程序以及询问的值在交互开始之前已经完全确定,不会根据和你的程序的交互过程动态构造,因此题目中的交互操作都是确定性的,你不需要关心这些操作在交互库中的具体实现。
数据保证在调用次数限制下,交互库运行所需的时间不超过 0.5s;交互库使用的内存大小固定,且不超过 128MB。
测试程序方式
试题目录下的 grader.cpp
是我们提供的交互库参考实现,最终测试时所用的交互库实现与该参考实现有所不同,因此选手的解法不应该依赖交互库实现。
- 你需要在本题目录下使用如下命令编译得到可执行程序:
g++ grader.cpp sample.cpp -o sample -O2 -lm
- 对于编译得到的可执行程序:
- 可执行文件将从标准输入读入以下格式的数据:
- 第一行包含三个整数 $m,K,Q$。
- 接下来 $Q$ 行,一行一个正整数,表示一次 蒜斜 的询问。
- 读入完成之后,交互库将调用恰好一次函数 $\texttt{solve}$,和 $Q$ 次函数 $\texttt{query}$ 你的函数正确返回后,交互库会判断你的计算是否正确,若正确则会输出
Correct
和交互函数调用次数相关信息,否则会输出相应的错误信息。
- 可执行文件将从标准输入读入以下格式的数据:
试题目录下有出题人提供的一份参考代码 sample.cpp
,注意这份代码 不保证可以通过所有的测试用例 。
数据范围
本题严禁任何形式的攻击交互库的行为,一旦发现,将取消相关选手的参赛资格。
Small Task: 蒜斜保证程序中仅包含 $\mathrm{xor}$ 操作,且 $\mathrm{xor}$ 语句中的 $b,c$ 均不是常量。
Large Task: 无特殊限制
对于所有数据,满足 $1 \le m \le 3,Q = 101,K = 2000$
时间限制: $1\texttt{s}$
空间限制: $512\texttt{MB}$