「HLOI2015」Tree
题目描述
Chavo 有一颗水晶树,树上会结出魔法水晶。包括树根在内,树一共有
Chavo 想要释放
输入
第一行输入整数
第二行输入
接下来
接下来
输出
输出一个整数代表经过所有操作后整棵树上所有节点数的和,结果要对
样例输入
1 | 3 2 |
样例输出
1 | 19 |
样例说明
第一次操作时,更新
第二次操作时,更新
最后求和为
数据范围及约定
对于
对于
对于
时间限制与空间限制
时间限制:
题解
推式子
注意,
树上实现子树修改和查询,搞出来个 DFS 序就变成了区间问题,线段树即可解决。
但是这什么鬼畜修改。这个类似于斐波那契数列的递推关系。
先看看
如果我们定义一个类斐波那契数列
那么就可以想到如下两种算法。
算法一
注意到修改可以分为两部分,是给这个点的子树内所有节点的权值先乘上
时间复杂度为
算法二
算法一中,需要区间乘,区间加,区间覆盖,虽然很快但不好敲代码(好吧我承认其实也挺好写的……),所以考虑用一个矩阵乘法完成所有操作。
线段树中叶子节点维护的矩阵
其中,
每次修改需要乘的矩阵
其中,
那么这么乘能乘出来些什么?
为了方便,令:
发现
那么,
更新一个节点后,矩阵就是这样的:
那么,如何更新答案?
对于线段树矩阵,更新一个区间时
最后,将线段树上非叶子节点全部下传清为单位矩阵后,统计答案。即将矩阵中的
时间复杂度为
代码见这里。