「HLOI2015」Tree

题目描述

Chavo 有一颗水晶树,树上会结出魔法水晶。包括树根在内,树一共有 个分叉的节点,其中 号节点为树根,初始状态下每一个节点都有一个生长值 。Chavo 有一根法杖,法杖可以对某个节点 释放生长法术,使得以 为根的子树的每个节点的生长值更新为 。对于每一个被更新的节点来说, 的定义都不一样,其中 是在释放法术之前被更新节点的生长值, 是在释放法术之前节点 的生长值。但是对于所有被更新的节点来说, 的递推公式都一样,是

Chavo 想要释放 次生长法术,每次法术都给定 ,她想问问你释放法术之后所有节点的生长值的和是多少?结果要对 取模后输出。

输入

第一行输入整数

第二行输入 个整数,第 个整数代表第 个节点上初始值

接下来 行,每一行有两个正整数 ,代表树上第 个节点和第 个节点有树杈相连;

接下来 行,每一行有 个正整数 ,如题目描述。

输出

输出一个整数代表经过所有操作后整棵树上所有节点数的和,结果要对 取模后输出。

样例输入

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

样例输出

1
19

样例说明

第一次操作时,更新 号点,对于 号点,,更新后 号点值为 ,同理 号点值为

第二次操作时,更新 号点,,更新后 号点为

最后求和为

数据范围及约定

对于 的数据,

对于 的数据,

对于 的数据,

时间限制与空间限制

时间限制:,空间限制:

题解

推式子

注意, 是对于子树内每个点说的……每个点的 不一定相同,不过都是该点的权值。

树上实现子树修改和查询,搞出来个 DFS 序就变成了区间问题,线段树即可解决。

但是这什么鬼畜修改。这个类似于斐波那契数列的递推关系。 先看看 的一些值有什么规律:

如果我们定义一个类斐波那契数列 就可以这样描述了:

那么就可以想到如下两种算法。

算法一

注意到修改可以分为两部分,是给这个点的子树内所有节点的权值先乘上 ,再加上 。于是先做一个区间乘法,然后利用矩阵算出要加的部分,最后做一个区间加法即可。

时间复杂度为 ,空间复杂度为

算法二

算法一中,需要区间乘,区间加,区间覆盖,虽然很快但不好敲代码(好吧我承认其实也挺好写的……),所以考虑用一个矩阵乘法完成所有操作。

线段树中叶子节点维护的矩阵 这样构造:

其中, 为此时这个节点的的权值,线段树上非叶子节点维护的都是单位矩阵,方便之后下传矩阵。

每次修改需要乘的矩阵 是两个矩阵的乘积:

其中, 是节点 的生长值, 意义与题中相同。

那么这么乘能乘出来些什么?

为了方便,令:

发现 这个矩阵是这样的:

那么, 就是这样的:

是这样的:

更新一个节点后,矩阵就是这样的:

的位置顺利被 替代,构造成功。

那么,如何更新答案?

对于线段树矩阵,更新一个区间时 矩阵乘 ,每次查询节点 的生长值时,将这一区间矩阵下传,之后清为单位矩阵。

最后,将线段树上非叶子节点全部下传清为单位矩阵后,统计答案。即将矩阵中的 加起来。

时间复杂度为 ,空间复杂度为

代码见这里