#P15061. 琥峪枫

琥峪枫

题目背景

不要 #include "tree.h"\texttt{\#include "tree.h"}

你需要在文件头加入以下内容,并且使用 C++17 或以上的语言规范提交本题:

long long ask(int u, int d);

题目描述

这是一道交互题。

给定一个正整数 hh。我们令 n=2h1n=2^h-1

交互库隐藏了一个 1n1 \sim n 的排列 pp 和一个长度为 nn 且每个元素均为不大于 10910^9正整数的序列 ff

现在有一棵深度为 hh,包含 nn 个结点的满二叉树 GG,根结点为 11 号结点。同时,对于任意一个满足 2un2 \le u \le n 的结点 uu,都满足其父亲结点为结点 u2\left\lfloor\dfrac u 2\right\rfloor

每次询问,你可以选择两个满足 1un1 \le u \le n1d1091 \le d \le 10^9 的整数 u,du,d,交互库会返回所有满足 dis(pu,v)=d\operatorname{dis}(p_u,v)=d 的结点 vv 所对应的 fvf_v 之和。特别的,若没有满足条件的结点 vv,则交互库会返回 00

其中,dis(u,v)\operatorname{dis}(u,v) 的值等于结点 uu 和结点 vv 之间的简单路径所包含的边的数量。特别的,dis(u,u)=0\operatorname{dis}(u,u)=0

你需要在不超过 2hn2hn 次询问内求出 i=1nfi\sum\limits_{i=1}^n f_i 的值。选手得分与单组测试数据询问次数以及对于任意整数 uu对整数 u\boldsymbol u 进行询问的次数最大值有关。

保证排列 pp 和序列 ff 是固定的,即交互库可能是自适应的

实现细节

你需要实现以下函数:

long long solve(int subtask, int h);
  • subtask 表示测试点编号;
  • hh 表示二叉树的高度;
  • 该函数需要返回 i=1nfi\sum\limits_{i=1}^n f_i 的值;
  • 对于每个测试点,该函数可能会被交互库调用多次

选手可以通过调用以下函数向交互库发送一次询问:

long long ask(int u, int d);
  • uu 表示询问的中心结点,你需要保证 1un1 \leq u \leq n
  • dd 表示询问的距离限制,你需要保证 1d1091 \leq d \leq 10^9
  • 该函数将返回到点 pup_u 正好为 dd 的结点的 ff 值之和。

题目保证在规定的操作次数限制下,交互库运行所需的时间不超过 11 秒;交互库使用的内存大小固定,且不超过 32 MiB32 \text{ MiB}

交互示例

假设 h=2h = 2n=3n = 3,隐藏排列 p=[2,1,3]p = [2, 1, 3],结点权值 f=[11,45,14]f = [11, 45, 14],下面是一个合法的交互过程:

选手程序 交互库 说明
调用 tree(1, 2) 开始测试
调用 ask(1, 1) 返回 1111 距离 p1=2p_1 = 2 正好为 11 的点只有结点 11,权值总和为 1111
调用 ask(2, 1) 返回 5959 距离 p1=1p_1 = 1 正好为 11 的点有结点 2,32, 3,权值总和为 45+14=5945 + 14 = 59
调用 ask(3, 1) 返回 1111 距离 p1=3p_1 = 3 正好为 11 的点只有结点 11,权值总和为 1111
运行结束并返回 7070 向屏幕打印交互结果 交互结束,结果正确

提示

数据范围

对于所有测试数据保证:2h152 \leq h \leq 15,数据组数 1T15001 \leq T \leq 1\,500,所有数据中 nn 的和 n\sum n 不超过 10610^6

本题共 22 个测试点,每个测试点的分值和数据范围见下表。

测试点编号 分值 特殊性质
11 1010 保证 h=2h = 2,数据组数 T=100T = 100
22 9090 无特殊限制

评分方式

本题首先会受到和传统相同的限制,例如编译错误会导致整道题目得 00 分,运行时错误、超过时间限制、超过空间限制都会导致相应测试点得 00 分。选手只能在程序中访问自己定义的和交互库给出的变量或数据,及其相应的内存空间。尝试访问其他位置空间将可能导致编译错误或运行错误。

在每次 solve 函数调用中,程序使用的操作次数 qq 需要满足 q2hnq \leq 2hn 的限制,否则将会获得 00 分。

在上述条件基础上:

  • 在测试点 11 中,程序得到满分当且仅当 solve 函数返回的答案正确;

  • 在测试点 22 中,程序得到的分数将按照以下方式计算:

    • solve 函数返回的答案不正确,则获得 00 分;
    • solve 函数返回的答案均正确,则对于该测试点的所有测试数据分别计分:设程序使用的操作次数为 qq,对于任意整数 uu,对整数 uu 进行询问的次数最大值为 xx,则程序将获得 f(q)g(x)f(q) - g(x) 分,其中 f(q)f(q) 的计算方式为 qq 在下表中所有满足的条件中,对应分值的最大值:
    条件 分值
    q2n+3q \leq 2n + 3 9090
    q2n+4q \leq 2n + 4 8282
    q2n+5q \leq 2n + 5 7676
    q2n+h+2q \leq 2n + h + 2 7272
    q2n+h+4q \leq 2n + h + 4 6969
    q2n+2h+2q \leq 2n + 2h + 2 6666
    q2n+2h+4q \leq 2n + 2h + 4 6363
    q3n+3q \leq 3n + 3 5959
    q3n+5q \leq 3n + 5 5656
    q3n+h+4q \leq 3n + h + 4 5353
    q3n+2h+4q \leq 3n + 2h + 4 5050
    q4n+3q \leq 4n + 3 4343
    q4n+5q \leq 4n + 5 4040
    q4n+h+4q \leq 4n + h + 4 3737
    q4n+2h+4q \leq 4n + 2h + 4 3434
    q2hnq \leq 2hn 3030

    其中 g(x)g(x) 的计算方式如下表所示:

    xx g(x)g(x)
    4\leq 4 00
    =5= 5 1010
    =6= 6 1515
    >6> 6 2020