#D0978. 隐藏数列
隐藏数列
题目描述
Tom 把 个正整数写成一排,记作 ,每一个都不超过 。33DAI 看不到这些数,只能向 Tom 询问某一段的和:
- 给出 ,问「 是多少」。
33DAI 想知道的只有一件事:这 个数里最大值与最小值的差(也就是极差)。请你帮他问出来,并且问的次数要尽量少。
本题是函数式交互题。你不需要写 main 函数,只要实现下面两个函数(声明在随题下发的 recover.h 里):
void init(int t, int n);
long long recover();
init(t, n):每个测试点开始时调用一次。 是这个测试点里数组的组数, 是每组的长度(各组相同)。recover():求出当前这一组数组的极差并返回。每组开始时询问次数清零。
你可以调用下面这个函数向评测程序提问:
long long query(int l, int r);
- 返回 ,要求 。
- 若下标不合法,本测试点判为 Wrong Answer。
评分方式:记 为"这个测试点里,某一组问得最多的次数"。
- 只要有任何一组答错,本测试点得 分;
- 直接判 Wrong Answer;
- 要确定 个数至少需要 次询问,所以下界是 。 得满分; 时分数从满分线性降到一半; 时从一半线性降到 ; 得 分。
输入格式
本题没有传统意义上的输入文件:数据由评测程序(grader)读入,你只要实现上面两个函数。
随题下发的文件(见「附加文件」):
recover.h:接口声明;grader.cpp:示例评测程序,只用来在本地把你的程序跑起来;compile.sh:编译脚本。
本地编译命令(把你自己的代码保存为 foo.cc,与上面三个文件放在同一个目录):
g++ -o foo foo.cc grader.cpp -O2 -std=c++14
示例 grader 的本地输入格式是:第一行两个整数 ;之后 行每行 个整数, 就是这一组的隐藏数组。它会打印每一组用了多少次询问。
注意:示例 grader 只用于本地自测,它的数据格式、数据范围与判分方式都和正式评测不同; 正式评测使用另一份 grader,请以题面写明的接口与规则为准。
输出格式
不需要输出任何东西:recover() 的返回值就是答案,由评测程序收集。
样例
某个测试点里 、,两组隐藏数组分别是 与 。
第一组:
你的程序 评测程序
query(1, 2) -> 8 (a1 + a2 = 8)
query(1, 3) -> 16 (a1 + a2 + a3 = 16)
query(2, 3) -> 11 (a2 + a3 = 11)
recover() 返回 5 (最大值 8、最小值 3,极差 5)
第二组三个数都是 ,极差是 ,所以 recover() 返回 。
这个测试点里最多的一组问了 次、下界也是 ,所以 ,得满分。
提示
- 本题是函数式交互题:
recover.h、grader.cpp、compile.sh会随题目一起下发,你只提交实现init/recover的源文件。 - 每个测试点里有好几组数据,同一组内的询问次数单独统计,最后取最大的那个。
- 一共至少要 次询问才能定出 个数,请想想怎样用恰好 次询问把数组恢复出来。
- 注意 很小时(比如 、)的边界。
数据范围
对于所有测试数据,保证:
- ;
- ;
- 。
| 子任务 | 分值 | 特殊性质 | |
|---|---|---|---|
| 无 | |||
| 最大值/最小值出现在很靠后的位置 |
共 个测试点,每个测试点 分,按测试点计分(子任务 type: sum)。