QOJ.ac

QOJ

时间限制: 10 s 内存限制: 2048 MB 总分: 100 通信

#6529. Alice, Bob 和电路

统计

Cyberland Circuit Foundation 由 $n$ 名成员组成。每名成员都有一个喜爱的数字和一个唯一的名字(喜爱的数字不一定互不相同)。

成员之间发送了 $m$ 封信。每封信都有一个发送者和一个接收者,信的内容是发送者喜爱的数字。

每名成员计算他们收到的信件内容(发送者喜爱的数字)之和,并对 $65536$(即 $2^{16}$)取模,作为他/她的结果数字。

你的任务是确定所有成员的结果数字。

然而,情况并不像看起来那么简单。Alice、Bob 和 Circuit 决定以一种稍微复杂的方式解决这个问题:

  • Alice 知道所有 $n$ 名成员(名字和喜爱的数字),但对信件一无所知。她需要向 Circuit 发送一个长度不超过 $10^5$ 的二进制字符串。
  • Bob 知道所有 $m$ 封信(发送者和接收者的名字),但对成员信息一无所知。他需要向 Circuit 发送一个长度不超过 $10^5$ 的二进制字符串。
  • Circuit 可以接收 Alice 和 Bob 发送的二进制字符串,并随后生成一个包含 $16n$ 位的二进制字符串作为输出。然而,由于其计算能力有限,Circuit 只能执行基本的逻辑运算(例如 AND、OR、NOT)。

下面我们将详细介绍电路的工作原理。

电路细节

门是电路的基本元件。一个门由零个或两个布尔输入(取决于门的类型)和一个布尔输出组成。门有两种类型:输入门和计算门。

输入门没有输入,代表 Alice 和 Bob 发送的二进制字符串中的位。 将会有 $l_A + l_B$ 个输入门,编号从 $0$ 到 $(l_A + l_B - 1)$,其中 $l_A, l_B$ 分别是 Alice 和 Bob 发送的字符串长度。

  • 对于 $0 \le i < l_A$,第 $i$ 个门的输出是 Alice 发送字符串的第 $i$ 位;
  • 对于 $0 \le i < l_B$,第 $(i + l_A)$ 个门的输出是 Bob 发送字符串的第 $i$ 位。

计算门有两个输入,代表计算过程。 计算门的编号从 $(l_A + l_B)$ 开始。

  • 对于每个计算门,你需要提供两个相关门的编号作为输入,以及操作类型 $p(0 \le p \le 15)$。
  • 为了防止循环依赖,两个相关门的编号必须小于该计算门的编号。
  • 如果其两个相关门的输出分别为 $x_0$ 和 $x_1$($x_0, x_1 \in \{0, 1\}$),则计算门的输出为: $$f(p, x_0, x_1) = \left\lfloor \frac{p}{2^{x_0 + 2x_1}} \right\rfloor \pmod 2$$

以下是一些可能有用的示例:

$x_0$ $x_1$ $x_0 \text{ AND } x_1$
$f(8, x_0, x_1)$
$x_0 \text{ OR } x_1$
$f(14, x_0, x_1)$
$x_0 \text{ XOR } x_1$
$f(6, x_0, x_1)$
$\text{NOT } x_0$
$f(5, x_0, x_1)$
0 0 0 0 0 1
1 0 0 1 1 0
0 1 0 1 1 1
1 1 1 1 0 0

实现细节

请注意:

  • 所有数组下标从 $0$ 开始。例如,如果 $a$ 是一个长度为 $n$ 的数组,则 $a[0]$ 到 $a[n-1]$ 是有效数据,访问超出该范围的下标可能会导致越界错误。
  • 所有字符串均以空字符 \0 结尾。

你需要实现以下过程:

Alice

int alice(const int n, const char names[][5],
 const unsigned short numbers[], bool outputs_alice[]);
方向 长度 含义 约束
输入 $n$ $1$ $n$ $0 \le n \le 700$
输入 names $n$ 每个成员的名字。 所有名字互不相同,仅由小写英文字母组成,最大长度为 4 个字符。
输入 numbers $n$ 每个成员喜爱的数字。 每个数字在 $0$ 到 $65535$ 之间。
输出 outputs_alice $l_A$ 发送给 Circuit 的二进制字符串。
输出 (返回值) $1$ $l_A$ 你需要确保 $l_A$ 不超过 $10^5$,且当 $n$ 相同时,$l_A$ 必须固定。

Bob

int bob(const int m, const char senders[][5],
 const char recipients[][5], bool outputs_bob[]);
方向 长度 含义 约束
输入 $m$ $1$ $m$ $0 \le m \le 1000$
输入 senders $m$ 每封信的发送者名字。 所有名字均出现在 Alice 的输入中。
输入 recipients $m$ 每封信的接收者名字。
输出 outputs_bob $l_B$ 发送给 Circuit 的二进制字符串。
输出 (返回值) $1$ $l_B$ 你需要确保 $l_B$ 不超过 $10^5$,且当 $m$ 相同时,$l_B$ 必须固定。

Circuit

为了确保 Circuit 的计算过程类似于通用电路,你不能直接获取 Alice 和 Bob 发送给 Circuit 的二进制字符串。你只知道这两个字符串的长度并输出电路结构。

int circuit(const int la, const int lb, int operations[],
 int operands[][2], int outputs_circuit[][16]);
方向 长度 含义 约束
输入 la $1$ $l_A$
输入 lb $1$ $l_B$
输出 operations $l$ 电路中每个门执行的操作类型。 $0$ 到 $15$ 之间的整数。
输出 operands $l$ 电路中每个门使用的操作数。 该数字必须小于当前门的编号。
输出 outputs_circuit $n$ 电路输出的门编号。 outputs_circuit[i][j] 表示第 $i$ 名成员最终结果的第 $j$ 位(从最低有效位开始计数)。成员按 Alice 的输入顺序排列。
输出 (返回值) $1$ $l$,表示总门数(包括输入门)。 你需要确保 $l \le 2 \times 10^7$

虽然你可以修改 operationsoperands 数组中索引小于 $l_A + l_B$ 的门的信息,但评测程序会忽略此类修改。

数据范围

对于所有测试用例:

  • $0 \le n \le 700, 0 \le m \le 1000$。
  • 所有名字互不相同,仅由小写英文字母组成,最大长度为 4 个字符。
  • 每名成员喜爱的数字在 $0$ 到 $65535$ 之间。
  • 所有发送者和接收者的名字均出现在 Alice 的输入数组 names 中。
  • alice()bob() 的内存限制为 $2048 \text{ MiB}$,时间限制分别为 $0.02$ 秒。
  • circuit() 的内存限制为 $2048 \text{ MiB}$,时间限制为 $7$ 秒。

在最终评估中,alice()bob() 在单个测试用例中可能会被多次调用。$0.02$ 秒的时间限制适用于每次调用。

子任务

子任务 A(12 分)

子任务 1, 2, 3 属于子任务类型 A,其中 $n = 1$。 每个子任务具有以下附加约束: 子任务 1(4 分):$m = 0$。 子任务 2(4 分):$0 \le m \le 1$。 * 子任务 3(4 分):$0 \le m \le 1000$。

子任务 B(54 分)

子任务 4, 5, 6 属于子任务类型 B,其中: $0 \le n \le 30, \frac{n}{2} \le m \le n^2$。 不存在两封信的发送者和接收者完全相同。 所有成员的名字都出现在 Bob 的输入中(即每名成员要么至少发送一封信,要么至少收到一封信)。 每个子任务具有以下附加约束: 子任务 4(24 分):$n = 26$,所有成员的名字均为单个小写字母,且在 Alice 的输入中按从 az 的顺序出现。 子任务 5(24 分):$n = 26$。 * 子任务 6(6 分):无特殊限制。

子任务 C(34 分)

子任务 7, 8, 9 属于子任务类型 C,其中 $0 \le n \le 700, 0 \le m \le 1000$。 每个子任务具有以下附加约束: 子任务 7(18 分):$n = 676$,所有成员的名字均为两个小写字母,且在 Alice 的输入中按字典序出现(例如 aa, ab, ac, ..., az, ba, ..., bz, ca, ..., zz)。 子任务 8(10 分):$n = 676$。 * 子任务 9(6 分):无附加约束。

样例

样例评测程序按以下格式读取输入: 第 1 行:$n \ m$ 第 $2 + i$ 行($0 \le i \le n - 1$):names numbers * 第 $2 + n + i$ 行($0 \le i \le m - 1$):senders recipients

样例评测程序按以下格式输出: 如果程序成功完成,样例评测程序将输出 $n$ 行,每行包含一个整数,表示你为每名成员实现的函数所计算出的最终结果。 否则,评测程序将不会向标准输出输出任何内容,并将错误信息打印到目录下的 abc.log 文件中。 * 此外,样例评测程序会将 $l_A, l_B, l$ 的值以及每个函数的运行时间输出到 abc.log

样例评测程序不会检查内存限制,也不会检查“对于相同的 $n/m$,$l_A/l_B$ 必须相等”这一限制。

Editorials

IDTypeStatusTitlePosted ByLast UpdatedActions
EditorialOpen Official EditorialQingyu- Download

Discussions

About Discussions

The discussion section is only for posting: General Discussions (problem-solving strategies, alternative approaches), and Off-topic conversations.

This is NOT for reporting issues! If you want to report bugs or errors, please use the Issues section below.

Open Discussions 0
No discussions in this category.

Issues

About Issues

If you find any issues with the problem (statement, scoring, time/memory limits, test cases, etc.), you may submit an issue here. A problem moderator will review your issue.

Guidelines:

  1. This is not a place to publish discussions, editorials, or requests to debug your code. Issues are only visible to you and problem moderators.
  2. Do not submit duplicated issues.
  3. Issues must be filed in English or Chinese only.
Active Issues 0
No issues in this category.
Closed/Resolved Issues 0
No issues in this category.