luogu#P10537. [APIO2024] 九月

[APIO2024] 九月

题目背景

请勿使用 C++14(GCC9) 提交

杭州市的中心广场有一棵著名的古树。这棵古树可以看作一棵 NN 个节点的有根树,节点编号从 00N1N - 1,其中 00 号节点是根节点。

称没有孩子的节点为叶子节点。古树每次落叶时,会选择一个当前的叶子节点删去。每一天中,古树可能会多次落叶。

MM 位志愿者(编号从 00M1M - 1)负责看护古树。每一位志愿者将各自按照如下方式独立记录今年的落叶的情况:

每一天,收集所有新的落叶的编号(即当天删除的节点的编号),然后将它们按任意顺序写在先前的落叶编号之后。

例如:第一天,叶子 3344 落下,于是他们写下 3,43, 44,34, 3。第二天,叶子 1122 落下,于是他们继续写下 1,21, 22,12, 1。最终的记录可能为 (3,4,1,2)(3, 4, 1, 2)(4,3,1,2)(4, 3, 1, 2)(3,4,2,1)(3, 4, 2, 1)(4,3,2,1)(4, 3, 2, 1) 中的任意一个。

这个过程持续了 KK 天,每天都有新的叶子掉落,直到只剩根节点为止。

你在旅途过程中经过了杭州。此刻已是寒冬,仰望古树光秃秃的枝干,你不禁想起落叶纷飞的美丽景象。

你很想知道今年有几天能看见落叶,但你只能找到 MM 位志愿者的记录。尝试根据这些记录推断出 KK 可能的最大值。

题目描述

你无需在程序开头引入库 september.h

你只需要实现以下函数:

int solve(int N, int M, std::vector<int> F,
            std::vector<std::vector<int>> S);
  • NN:古树的节点数量。
  • MM:志愿者的数量。
  • FF:一个长度为 NN 的数组。对于 1iN11 \le i \le N - 1F[i]F[i] 表示节点 ii 的父亲节点的编号。F[0]F[0] 始终为 1-1
  • SS:一个长度为 MM 的数组。SS 中的每个元素是一个长度为 N1N - 1 的数组。S[i][j]S[i][j] 表示志愿者 ii 记录的第 jj 个节点编号(从 00 开始)。
  • 该函数必须返回一个整数,表示根据如上规则的 KK 可能的最大值(即,最大可能的落叶天数)。
  • 对于每个测试点,交互库可能调用该函数多于一次。每次调用都应该作为新的情况分别处理。

注意:由于函数调用可能会发生多次,选手需要注意之前调用的残余数据对于后续调用的影响,尤其是全局变量的状态。

输入格式

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

  • 第 1 行:TT

对于接下来 TT 组数据中的每一组:

  • 11 行:N MN\ M
  • 22 行:F[1] F[2]  F[N1]F[1]\ F[2]\ \ldots\ F[N - 1]
  • 3+i (0iM1)3 + i\ (0 \le i \le M - 1) 行:S[i][0] S[i][1] S[i][2]  S[i][N2]S[i][0]\ S[i][1]\ S[i][2]\ \ldots\ S[i][N - 2]

输出格式

评测程序示例按照如下格式打印你的答案:

对于每组测试数据:

  • 第 1 行:函数 solve 的返回值
1
3 1
0 0
1 2
2
1
5 2
0 0 1 1 
1 2 3 4
4 1 2 3
1

提示

样例解释

对于样例一,考虑如下调用:

solve(3, 1, {-1, 0, 0}, {{1, 2}});

对应的树如下图所示:

叶子 1122 可能在同一天落下,或者叶子 11 在第一天先落下,然后叶子 22 在第二天落下。落叶天数不超过 22

因此,程序应当返回 22

对于样例二,考虑如下调用:

solve(5, 2, {-1, 0, 0, 1, 1}, {{1, 2, 3, 4}, {4, 1, 2, 3}});

对应的树如下图所示:

假设至少有 22 天落叶,根据志愿者的记录,叶子 44 将在不同的日子(第一天和最后一天)落下,这是矛盾的。

因此,程序应当返回 11

数据范围

  • 2N1052 \le N \le 10^5
  • 1M51 \le M \le 5
  • NM8×105\sum NM \le 8 \times 10^5
  • F[0]=1F[0] = -1 且对于 1iN11 \le i \le N - 1, 0F[i]i10 \le F[i] \le i - 1
  • 对于 1iM11 \le i \le M - 1, 数组 S[i]S[i] 是一个 1,2,,N11, 2, \ldots , N - 1 的排列
  • 保证 FF 描述的是一棵以节点 00 为根的有根树

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

子任务编号 附加限制 分值
1 M=1,N10,N30M=1,N\le 10,\sum N\le 30 1111
2 N10,N30N\le 10,\sum N\le 30 1414
3 M=1,N1000,N2000,F[i]=i1M=1,N\le 1\,000,\sum N\le 2\,000,F[i]=i-1 55
4 M=1,N1000,N2000M=1,N\le 1\,000,\sum N\le 2\,000 99
5 N1000,N2000,F[i]=i1N\le 1\,000,\sum N\le 2\,000,F[i]=i-1 55
6 N1000,N2000N\le 1\,000,\sum N\le 2\,000 1111
7 M=1,F[i]=i1M=1,F[i]=i-1 99
8 M=1M=1 1111
9 F[i]=i1F[i]=i-1 99
10 没有额外的约束条件 1616