这是一道通信题
有一个长为 N 的,由 [0,N−1] 内的整数构成的排列 P0,P1,⋯,PN−1。Anna 想要知道 PL,PL+1,⋯,PR 中,最小的元素的下标是多少。但是 Anna 只知道 n,L,R 的值,不知道排列 P 的具体信息。
另一方面,Bruno 知道 N 的值与整个排列 P0,P1,⋯,PN−1,但他却不知道 Anna 所询问的 L,R 的值。
为了让 Anna 得到这个最小的下标,Anna 与 Bruno 之间可以互相发送信息。他们之间所发送的每个字符只能是 0
或 1
,即每次一方可以向另一方发送一个 bit 的信息。由于通信仪器的限制,Alice 只能向 Bruno 发送至多 18 个 bit 的信息,而 Bruno 只能向 Alice 发送至多 10000 个 bit 的信息。
注意,Bruno 向 Anna 发送的信息数量上界仅为评测时使用的一个硬性上界,为了取得满分,Bruno 实际向 Anna 发送的信息不能超过 300 个 bit。
编写一个程序,实现 Anna 与 Bruno 两个人之间的策略。
实现细节
你需要提交两个文件。
Anna
你所需要提交的第一个文件为 Anna.cpp
,它需要实现 Anna 的策略。你需要包含头文件 Anna.h
,并实现以下函数:
void InitA(int N, int L, int R)
在每组测试数据中,该函数将会被调用恰好一次。
- 参数中的
N
表示排列的长度 N - 参数中的
L
与R
表示 Anna 所询问的 L 与 R。
void ReceiveA(bool x)
每当 Bruno 向 Anna 发送一个字符时,该函数会被调用。
- 参数中的
x
描述 Bruno 向 Anna 所发送的字符。其中true
表示这个字符为1
,false
表示这个字符为0
。
int Answer()
该函数会在信息传递完成后被调用恰好一次。该函数需要返回 Anna 所询问的最小元素的下标。
在该文件中,你可以调用以下函数:
void SendA(bool y)
Anna 通过调用该函数向 Bruno 发送一个字符。
- 参数中的
y
描述 Anna 向 Bruno 所发送的字符。其中true
表示这个字符为1
,false
表示这个字符为0
。
Bruno
你所需要提交的第一个文件为 Bruno.cpp
,它需要实现 Bruno 的策略。你需要包含头文件 Bruno.h
,并实现以下函数:
void InitB(int N, std::vector<int> P)
在每组测试数据中,该函数将会被调用恰好一次。
- 参数中的
N
表示排列的长度 N - 参数中的
P
描述一个长为 N 的数组。其中对每个 0≤i≤N−1,P[i]
即为排列中 Pi 的值。
void ReceiveB(bool y)
每当 Anna 向 Bruno 发送一个字符时,该函数会被调用。
- 参数中的
y
描述 Anna 向 Bruno 所发送的字符。其中true
表示这个字符为1
,false
表示这个字符为0
。
在该文件中,你可以调用以下函数:
void SendB(bool x)
Bruno 通过调用该函数向 Anna 发送一个字符。
- 参数中的
x
描述 Bruno 向 Anna 所发送的字符。其中true
表示这个字符为1
,false
表示这个字符为0
。
实现细节
你可以假设你的程序会通过如下方式进行执行:
对于每组测试数据,评测系统准备了两个队列:QY 存储由 Anna 发送的字符,QX 存储由 Bruno 发送的字符。在评测开始时,函数 InitA
与 InitB
将被调用,双方所发送的字符将被置入对应的队列中。随后,将不断重复以下过程:
- 如果 Qx 与 Qy 有任意一个队列非空,则从对应的队列中弹出一个字符,并调用对应的函数。如果两个队列均非空,则会随机选择一个队列进行对应的调用。
- 每当
SendA
被调用时,所发送的字符将被压入 QY。 - 每当
SendB
被调用时,所发送的字符将被压入 QX。
- 每当
- 如果两个队列均为空,则会调用函数
Answer
,随后程序将被终止。
样例交互库
样例交互库将从标准输入中按照以下格式读入数据:
N L R
P[0] P[1] ... P[N-1]
当程序成功结束后,样例交互库将输出以下信息到标准输出:
- 如果你的答案正确,它将输出 Anna 向 Bruno 发送的字符总数 Y 与 Bruno 向 Anna 发送的字符总数 X,具体格式为
Accepted: Y X
。 - 如果你的答案错误,它将输出
Wrong Answer[X]
。
子任务
对于所有数据:
- 1≤N≤1000000
- 0≤L≤R≤N−1
- 1≤Pi≤N(0≤i≤N−1)
- Pi≠Pj(0≤i<j≤N−1)
每个子任务的分值如下:
- Subtask 1(1 point): N≤1000
- Subtask 2(9 points): N≤10000
- Subtask 3(90 points): 没有额外的限制。
- 设 T 为 Bruno 向 Anna 发送的字符总数。
- 你在每个测试点中的得分将通过以下方式计算:
- 若 5000<T≤10000,你的得分为 25×10000−T5000
- 若 1000<T≤5000,你的得分为 25+40×5000−T4000
- 若 300<T≤1000,你的得分为 65+25×1000−T700
- 若 T≤300,你的得分为 90