#loj5622. 「KTSC 2026 R2」五万种调味汁

    ID: 9664 传统题 3000ms 2048MiB 尝试: 1 已通过: 1 难度: 10 上传者: 标签>KTSC2026容斥原理交互题Special Judge提高+/省选−

「KTSC 2026 R2」五万种调味汁

AdditionalFile5622.zip

#5622. 「KTSC 2026 R2」五万种调味汁

标签: 传统 | 时间限制: 3000 ms | 内存限制: 2048 MiB |

注意事项

在 LibreOJ 上,由于语言限制,目前只支持以下语言的提交:

  • C++(标准为 C++ 17 及以上)

请在提交源代码前添加 #include "sauce.h"

题目描述

题目译自 2026년도 국제정보올림피아드 대표학생 선발고사 - 2차 선발고사 T1 「오만가지 소스

金东贤大厨自诩能够制作出「五万种」调味汁。事实果真如此吗?你现在是烹饪大赛的评委,需要通过测试来评估金东贤大厨制作调味汁的能力。

赛场共有 NN 种食材,每种食材分别编号为 0,1,,N10, 1, \ldots, N-1。金东贤大厨可以制作的每种调味汁都由其中的 22 种或 33 种食材组成。对于任意两种不同的调味汁,它们所包含的食材列表不能完全相同(尽管部分食材可能会重叠)。

从数学角度来看,金东贤大厨能制作的调味汁是集合 XX 中的元素。XX 的每个元素 SS 都是 {0,1,,N1}\{0, 1, \ldots, N-1\} 的一个子集,且满足 S|S|2233。根据集合的标准定义,每个 SS 中不包含重复元素。

作为评委,你需要确定金东贤大厨能制作的调味汁总数 X|X|。虽然你无法直接获得关于 XX 的完整信息,但可以通过“盲测”来获取相关情报。

盲测的流程如下:

  • 你可以选择食材 {0,1,,N1}\{0, 1, \ldots, N-1\} 的一个子集 YY 放入锅中交给大厨。由于锅的容积有限,一次能放入的食材数量 Y|Y| 不能超过 N/2+1\lceil N/2 \rceil + 1。即必须满足 YN/2+1|Y| \leq \lceil N/2 \rceil + 1。其中 t\lceil t \rceil 表示大于或等于实数 tt 的最小整数。
  • 金东贤大厨会告诉你,他仅利用锅里的食材 YY 总共能制作出多少种调味汁。也就是说,大厨会向你返回 f(Y)={SXSY}f(Y) = |\{S \in X \mid S \subseteq Y\}|

你的目标是通过尽可能少的盲测次数,准确地求出 X|X|

实现细节

你需要实现以下函数:

int solve(int N)
  • NN:食材的总数。
  • 该函数应返回 X|X| 的值。
  • 该函数仅会被调用一次。

该函数可以调用以下函数:

int query(vector<int> Y)
  • YY 的每个元素代表食材的编号。
  • YY 中的元素必须互不相同。
  • 必须满足 0Y[i]N10 \leq Y[i] \leq N-1(对于 0iY10 \leq i \leq |Y|-1)。
  • 必须满足 YN/2+1|Y| \leq \lceil N/2 \rceil + 1
  • 该函数返回 f(Y)={SXSY}f(Y) = |\{S \in X \mid S \subseteq Y\}|
  • 在单个测试用例中,该函数最多可调用 30003000 次。

样例

假设 N=6N=6,金东贤大厨能制作的调味汁集合为 X={{0,1},{2,3,4}}X = \{ \{0, 1\}, \{2, 3, 4\} \}。则 X=2|X|=2。 锅的最大容量为 6/2+1=4\lceil 6/2 \rceil + 1 = 4。 评测程序最初调用如下函数: solve(6) 选手的代码可能会进行如下交互:

query({0, 1, 2})
query({2, 3, 4})
query({0, 2, 3, 5})
  • 由于 {0,1}{0,1,2}\{0, 1\} \subseteq \{0, 1, 2\}{2,3,4}⊈{0,1,2}\{2, 3, 4\} \not\subseteq \{0, 1, 2\}query({0, 1, 2}) 返回 11
  • 由于 {0,1}⊈{2,3,4}\{0, 1\} \not\subseteq \{2, 3, 4\}{2,3,4}{2,3,4}\{2, 3, 4\} \subseteq \{2, 3, 4\}query({2, 3, 4}) 返回 11
  • 由于 {0,2,3,5}\{0, 2, 3, 5\} 不包含 XX 中的任何元素,query({0, 2, 3, 5}) 返回 00

选手的代码作为 solve(6) 的返回值返回 22,即提交了正确答案。

数据范围与提示

对于所有输入数据,满足:

  • 6N10006 \leq N \leq 1000
  • 1X500001 \leq |X| \leq 50000
  • 对于所有 SXS \in X,满足 S{2,3}|S| \in \{2, 3\}
  • 在此题目中,评测程序不是自适应的(non-adaptive)。这意味着集合 XX 在调用 solve 之前就已经确定。

详细子任务附加限制及分值如下表所示。

子任务 分值 附加限制
11 1111 N500N \leq 500;对于 XX 中任意两个不同元素 Si,SjS_i, S_j,满足 SiSj=S_i \cap S_j = \emptyset;且对于所有 SXS \in X,满足 $
22 3232 N500N \leq 500;对于 XX 中任意两个不同元素 Si,SjS_i, S_j,满足 SiSj=S_i \cap S_j = \emptyset
33 2525 对于所有 SXS \in X,满足 $
44 3232 无附加限制

在每个子任务中,如果你的程序有任何一次未能准确返回 X|X| 的值,则该子任务得 00 分。

如果你在某个子任务的所有测试用例中都能准确返回 X|X|,则该子任务的得分计算规则如下:设该子任务所有测试用例中使用的最大查询次数(调用 query 的次数)为 QQ

子任务 1 和 2

如果 Q3000Q \leq 3000,则获得该子任务 100%100\% 的分数。

子任务 3 和 4

得分根据以下公式计算:

  • 如果 41<Q300041 < Q \leq 3000,则该子任务得分乘以以下比例:
0.5+412Q0.5 + \frac{41}{2Q}
  • 如果 Q41Q \leq 41,则获得该子任务 100%100\% 的分数。

示例评测程序

示例评测程序的输入格式如下:

  • 第一行:NN
  • 第二行:KK(即 X|X|
  • 接下来的 KK 行(对于 0i<K0 \leq i < K):
    • 3+i3+i 行:L a0 a1  aL1L \ a_0 \ a_1 \ \ldots \ a_{L-1}
    • 满足 2L32 \leq L \leq 3
    • 0ajN10 \leq a_j \leq N-1
    • a0,a1,,aL1a_0, a_1, \ldots, a_{L-1} 互不相同
    • {a0,a1,,aL1}\{a_0, a_1, \ldots, a_{L-1}\} 是集合 XX 的一个元素

示例评测程序会按以下格式输出你的代码在 solve 函数中返回的值以及调用 query 的次数:

  • 第一行:solve 函数返回的值 xx
  • 第二行:调用 query 的次数 QQ