P14351 [JOISC 2019] 矿物 / Minerals

题目背景

在洛谷上提交本题,需要定义函数 `int Query(int x);`、`void Answer(int a, int b);` 而非引用头文件 `minerals.h`。

题目描述

JOI 教授的实验室正在研究 $N$ 种矿物。每种矿物有 2 片样本,总共有 $2N$ 片样本,编号从 $1$ 到 $2N$。 某天,助手 Bitaro 不慎将装有这 $2N$ 片样本的盒子打翻,他已无法分辨哪两片样本属于同一种矿物。 实验室拥有一种设备,可通过测量每种矿物吸收的波长,来统计设备内当前包含的矿物种类数量。Bitaro 的任务是从 $2N$ 片样本中找出所有 $N$ 对同种矿物。初始时,设备内没有放入任何样本。Bitaro 可执行以下操作: - 将一片样本插入设备中,Bitaro 会得知设备内当前包含的矿物种类数量。 - 从设备中取出一片样本,Bitaro 会得知设备内当前包含的矿物种类数量。 为避免被 JOI 教授发现 Bitaro 惹出麻烦,他总共最多只能执行 $1\,000\,000$ 次操作。 请编写一个程序,给定矿物种类数 $N$,利用该设备,找出所有同种矿物的配对。 ### 实现细节 程序应实现以下函数: - `void Solve(int N)` 此函数在每个测试用例中**恰好被调用一次**。 - 参数 $N$ 表示矿物种类的数量。 你的程序可以调用以下函数: - `int Query(int x)` 对于你指定的样本编号 $x$,若该样本已在设备中,则将其取出;否则将其插入设备中。然后返回设备中当前包含的矿物种类数量。 - 你通过参数 $x$ 指定样本编号,必须满足 $1 \le x \le 2N$。否则,你的程序将被判定为 **Wrong Answer [1]**。 - 函数 `Query` 的调用次数不得超过 $1\,000\,000$ 次。否则,你的程序将被判定为 **Wrong Answer [2]**。 - `void Answer(int a, int b)` 使用此函数,你将输出同种矿物的配对。 - 参数 $a$ 和 $b$ 表示第 $a$ 片样本与第 $b$ 片样本属于同一种矿物。它们必须满足 $1 \le a \le 2N$ 且 $1 \le b \le 2N$。否则,你的程序将被判定为 **Wrong Answer [3]**。 - 若在 $a$ 或 $b$ 中,同一数值出现超过一次,你的程序将被判定为 **Wrong Answer [4]**。 - 若指定的样本属于不同种类的矿物,你的程序将被判定为 **Wrong Answer [5]**。 函数 `Answer` 必须**恰好被调用 $N$ 次**。若在函数 `Solve` 执行结束时,对 `Answer` 的调用次数不等于 $N$,你的程序将被判定为 **Wrong Answer [6]**。 ### 重要提示 - 你的程序可以为内部使用实现其他函数,或使用全局变量。 - 你的程序**不得**使用标准输入和标准输出,也不得通过任何方式与其他文件通信。但你的程序可以向 stderr 输出调试信息。 ### 编译与测试运行 你可以从竞赛网页下载一个归档文件,其中包含用于测试你程序的样例评测器。该归档文件还包含你程序的样例源代码文件。 样例评测器是文件 `grader.cpp`。为测试你的程序,请将 `grader.cpp`、`minerals.cpp` 和 `minerals.h` 放在同一目录下,并运行以下命令编译你的程序: ``` g++ -std=gnu++14 -O2 -o grader grader.cpp minerals.cpp ``` 当编译成功后,将生成可执行文件 `grader`。 请注意,实际评测器与样例评测器不同。样例评测器将以单进程方式运行,从标准输入读取输入数据,并将结果写入标准输出。

输入格式

样例评测器从标准输入读取以下数据: $N$ $X_1\ Y_1$ $\vdots$ $X_N\ Y_N$ 其中,$X_i$ 和 $Y_i$($1 \le i \le N$)表示第 $X_i$ 片样本与第 $Y_i$ 片样本属于同一种矿物。

输出格式

当程序成功终止时,样例评测器将以下信息写入标准输出(引号仅用于清晰说明): - 若你的程序被判定为正确,它将输出调用函数 `Query` 的次数,格式为 “Accepted: 100”。 - 若你的程序被判定为 **Wrong Answer**,它将输出其类型,格式为 “Wrong Answer [1]”。 若你的程序被判定为多种类型的 **Wrong Answer**,样例评测器仅报告其中一种。

说明/提示

### 样例 1 解释 | 调用 | 调用 | 返回值 | |:-------------:|:-------------:|:------:| | `Solve(4)` | | | | | `Query(1)` | 1 | | | `Query(2)` | 2 | | | `Query(5)` | 2 | | | `Query(2)` | 1 | | | `Answer(3, 4)`| (无) | | | `Answer(5, 1)`| (无) | | | `Answer(8, 7)`| (无) | | | `Answer(2, 6)`| (无) | ### 数据范围 关于 $X_i$ 和 $Y_i$ 的定义,请参阅“样例评测器的输入”部分。 - $1 \le N \le 43\,000$。 - $1 \le X_i \le 2N$($1 \le i \le N$)。 - $1 \le Y_i \le 2N$($1 \le i \le N$)。 - $X_i \ne X_j$($1 \le i < j \le N$)。 - $Y_i \ne Y_j$($1 \le i < j \le N$)。 - $X_i \ne Y_j$($1 \le i \le N$,$1 \le j \le N$)。 ### 子任务 1. (6 分)$N \le 100$。 2. (25 分)$N \le 15\,000$,且对所有 $1 \le i \le N$,满足 $1 \le X_i \le N$,$N + 1 \le Y_i \le 2N$。 3. (9 分)$N \le 15\,000$。 4. (30 分)$N \le 38\,000$。 5. (5 分)$N \le 39\,000$。 6. (5 分)$N \le 40\,000$。 7. (5 分)$N \le 41\,000$。 8. (5 分)$N \le 42\,000$。 9. (10 分)无额外约束。