#include "september.h"
#include <vector>
#include <algorithm>
int solve(int N, int M, std::vector<int> F, std::vector<std::vector<int>> S) {
// 1. 记录每个节点在所有志愿者记录中出现的最晚下标
std::vector<int> last_pos(N, 0);
for (int i = 0; i < M; ++i) {
for (int j = 0; j < N - 1; ++j) {
int node = S[i][j];
last_pos[node] = std::max(last_pos[node], j);
}
}
// 2. 核心修正:爸爸必须等孩子。
// 因为题目保证 F[i] < i,所以我们从大到小遍历,
// 这样处理每个节点时,它的孩子们(编号比它大的)肯定已经处理过了。
for (int i = N - 1; i >= 1; --i) {
int father = F[i];
if (father != 0) { // 根节点 0 不在记录里,不用管
last_pos[father] = std::max(last_pos[father], last_pos[i]);
}
}
// 3. 贪心统计:只要当前看到的所有节点,它们的“出场底线”都没超过当前下标,
// 就说明这一天可以结账了。
int max_days = 0;
int current_limit = 0;
for (int j = 0; j < N - 1; ++j) {
// 我们只看第一个志愿者的序列,配合已经更新过的 last_pos 即可
current_limit = std::max(current_limit, last_pos[S[0][j]]);
// 如果目前所有见到的节点,最晚的那个也没超出位置 j
if (current_limit == j) {
max_days++;
}
}
return max_days;
}