#P8361. [ioi2018国家队集训]树
[ioi2018国家队集训]树
树(tree)
题目描述
给定一棵有根树,共有 个节点,节点编号为 ,根节点为 。
对于每个 ,节点 的父亲为 。保证:
因此,每个节点的父亲编号都小于它本身的编号。
每个节点 有一个点权 ,满足:
定义一条长度为 的节点序列 是一条合法序列,当且仅当同时满足:
-
对于所有 ,有:
-
对于所有 ,节点 是节点 的祖先。
也就是说,序列中点权依次为 ,并且后一个节点必须是前一个节点的祖先。
现在会进行 次修改。第 次修改,其中 ,会把节点:
的点权修改为 。
令 表示第 次修改完成后,当前树上合法序列的数量。
你不需要输出每一次的 ,只需要计算:
$$O=\sum_{i=0}^{Q-1}(i+1)\times ans_i \pmod {10^9+7}$$你的任务是实现指定函数,返回 。
提交方式
本题为提交函数题。
你需要提交一个源文件,实现如下函数:
int calc(int N, int L, int Q,
std::vector<int> F,
std::vector<int> A,
std::vector<int> P);
评测程序会负责读入数据并调用你的 calc 函数。
你提交的代码中:
- 不应包含
main函数; - 不需要自行读入;
- 不需要自行输出;
- 只需要返回答案 。
参数说明
N:树的节点数。L:合法序列的长度,也是点权的取值范围。Q:修改次数。F:长度为 的数组,其中F[i]表示节点 的父亲。A:长度为 的数组,其中A[i]表示节点 的初始点权。P:长度为 的数组,其中P[i]表示第 次修改后的新点权。- 函数需要返回整数 。
样例
调用:
calc(6, 2, 6,
{0, 1, 0, 3, 0},
{1, 2, 1, 2, 1, 2},
{2, 1, 2, 1, 2, 1});
在这个样例中:
ans = [0, 0, 1, 1, 2, 2]
因此:
$$O=1\times 0+2\times 0+3\times 1+4\times 1+5\times 2+6\times 2=29$$所以函数应返回:
29
数据范围与限制
对于所有测试数据,满足:
子任务
- 分:,,。
- 分:,,。
- 分:对于所有 ,均有 。
- 分:,。
- 分:无特殊限制。
样例评测程序说明
样例评测程序会按照如下格式读入数据:
N L Q
F[0] F[1] ... F[N-2]
A[0] A[1] ... A[N-1]
P[0] P[1] ... P[Q-1]
然后调用:
calc(N, L, Q, F, A, P)
并输出该函数的返回值。
输出格式为:
O