#P15108. 白井黑子

    ID: 16832 远端评测题 1000~8000ms 257MiB 尝试: 0 已通过: 0 难度: 9 上传者: 标签>交互题Special JudgeO2优化Ad-hoc

白井黑子

题目背景

这是一道交互题。

请勿使用 C++14 (GCC 9) 提交。

此题是黑子测试你是否具有空间系超能力而制作的。

题目描述

给定一棵以 11 为根有根树,标号 11nn,求这棵树的 DFS 序。

具体地,有如下伪代码:

int d[n], tot = 0
set son[n]
void dfs(int u):
    d[tot] = u
    tot += 1
    for v in son[u]: // in any order
        dfs(v)
dfs(1)

dd 数组即为所求。

显然,一棵树可以有多个 DFS 序,你只要求出任意一个即可。

交互方式

我们定义了类型 Array 表示长度 nn,值域 [0,n][0,n] 的数组。你可以调用它的两个方法:

  1. int operator[](int x),表示获取该数组第 xx 位的值。必须满足 x[0,n]x\in[0,n]
  2. void set(int x,int y),表示将数组第 xx 位设置为 yy。必须满足 x[0,n]x\in [0,n] 以及 y[0,n]y\in[0,n]。调用 a.set(x,y) 后,a[x]a[x] 将返回 yy

所有方法的复杂度均为 O(1)O(1)

你需要编写一个函数 void dfs(int n, Array &f,Array &a)。其中 f[i]f[i] 的初始值为点 ii 的父亲,这里规定根的父亲为 00,且 f[0]=0f[0]=0a[i]a[i] 初始值全部为 00

该函数会被调用恰好一次。你需要在函数返回时,在 aa 中写入你求出的 DFS 序。具体地,对于每一个 i[1,n]i\in [1,n],最后一次调用 a.set(i,x)xx 需为 DFS 序的第 xx 项,a[0]a[0] 的值没有要求。

另外,你还可以调用函数 int fa(int x),它返回 f[x]f[x] 的初始值(xx 的父亲),要求 x[0,n]x\in[0,n]。注意,如果调用了该函数,仅能获得当前测试点 50%50\% 的分数。

本题实际的空间限制为 1MB,多余空间将由交互器消耗。需要注意的是,递归函数消耗的栈空间也计入空间限制。

请注意,任何绕过提供的方法而直接使用传入的类型空间的行为被视为攻击交互器,将会被判为 00 分。

下发文件中提供了 dfs.cpp,你可以在此程序的基础上编写代码。该代码已内置交互器,可以直接测试样例以及提交。你只需要完善其中的 dfs 函数。

输入格式

以下是提供给示例交互器的输入格式:

第一行,一个正整数 nn

接下来一行 n1n-1 个整数,表示 2n2\sim n 号结点的父亲。

输出格式

以下是提供给示例交互器的输出格式:

一行 nn 个整数,表示选手代码返回的 DFS 序。

6
6 5 1 1 5
1 5 3 6 2 4

提示

本题采用捆绑测试。

  • Subtask 1(20 pts):n105n\le 10^5,时限 1s。
  • Subtask 2(30 pts):n106n\le 10^6,时限 6s。
  • Subtask 3(30 pts):n5×106n\le 5\times 10^6,时限 6s。
  • Subtask 4(10 pts):对于 i1i\ge 1,初始有 f[i]<if[i]<i,时限 8s。
  • Subtask 5(10 pts):无特殊限制,时限 8s。

对于全部的测试点,1n1071\leq n\leq 10^7

你可以提交示例程序来测试交互器的运行时间。