sdoi.qoj.ac

qoj::sdoi

Time Limit: 2 s Memory Limit: 256 MB Total points: 100 Communication
[+1]
统计

这是一道通信题

有一个长为 N 的,由 [0,N1] 内的整数构成的排列 P0,P1,,PN1。Anna 想要知道 PL,PL+1,,PR 中,最小的元素的下标是多少。但是 Anna 只知道 n,L,R 的值,不知道排列 P 的具体信息。

另一方面,Bruno 知道 N 的值与整个排列 P0,P1,,PN1,但他却不知道 Anna 所询问的 L,R 的值。

为了让 Anna 得到这个最小的下标,Anna 与 Bruno 之间可以互相发送信息。他们之间所发送的每个字符只能是 01,即每次一方可以向另一方发送一个 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
  • 参数中的 LR 表示 Anna 所询问的 LR
void ReceiveA(bool x)

每当 Bruno 向 Anna 发送一个字符时,该函数会被调用。

  • 参数中的 x 描述 Bruno 向 Anna 所发送的字符。其中 true 表示这个字符为 1false 表示这个字符为 0
int Answer()

该函数会在信息传递完成后被调用恰好一次。该函数需要返回 Anna 所询问的最小元素的下标

在该文件中,你可以调用以下函数:

void SendA(bool y)

Anna 通过调用该函数向 Bruno 发送一个字符。

  • 参数中的 y 描述 Anna 向 Bruno 所发送的字符。其中 true 表示这个字符为 1false 表示这个字符为 0

Bruno

你所需要提交的第一个文件为 Bruno.cpp,它需要实现 Bruno 的策略。你需要包含头文件 Bruno.h,并实现以下函数:

void InitB(int N, std::vector<int> P)

在每组测试数据中,该函数将会被调用恰好一次。

  • 参数中的 N 表示排列的长度 N
  • 参数中的 P 描述一个长为 N 的数组。其中对每个 0iN1P[i] 即为排列中 Pi 的值。
void ReceiveB(bool y)

每当 Anna 向 Bruno 发送一个字符时,该函数会被调用。

  • 参数中的 y 描述 Anna 向 Bruno 所发送的字符。其中 true 表示这个字符为 1false 表示这个字符为 0

在该文件中,你可以调用以下函数:

void SendB(bool x)

Bruno 通过调用该函数向 Anna 发送一个字符。

  • 参数中的 x 描述 Bruno 向 Anna 所发送的字符。其中 true 表示这个字符为 1false 表示这个字符为 0

实现细节

你可以假设你的程序会通过如下方式进行执行:

对于每组测试数据,评测系统准备了两个队列:QY 存储由 Anna 发送的字符,QX 存储由 Bruno 发送的字符。在评测开始时,函数 InitAInitB 将被调用,双方所发送的字符将被置入对应的队列中。随后,将不断重复以下过程:

  • 如果 QxQy 有任意一个队列非空,则从对应的队列中弹出一个字符,并调用对应的函数。如果两个队列均非空,则会随机选择一个队列进行对应的调用。
    • 每当 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]

子任务

对于所有数据:

  • 1N1000000
  • 0LRN1
  • 1PiN(0iN1)
  • PiPj(0i<jN1)

每个子任务的分值如下:

  • Subtask 1(1 point): N1000
  • Subtask 2(9 points): N10000
  • Subtask 3(90 points): 没有额外的限制。
    • T 为 Bruno 向 Anna 发送的字符总数。
    • 你在每个测试点中的得分将通过以下方式计算:
      • 5000<T10000,你的得分为 25×10000T5000
      • 1000<T5000,你的得分为 25+40×5000T4000
      • 300<T1000,你的得分为 65+25×1000T700
      • T300,你的得分为 90