Arietta
问题描述
Arietta 的命运与她的妹妹不同,在她的妹妹已经走进学院的时候,她仍然留在山村中。
但是她从未停止过和恋人 Velding 的书信往来。一天,她准备去探访他。
对着窗外的阳光,临行前她再次弹起了琴。
她的琴的发声十分特殊。
让我们给一个形式化的定义吧。
所有的 $n$ 个音符形成一棵由音符 $C$ ( 1 号节点) 构成的有根树,每一个音符有一个音高$ H_i$ 。
Arietta 有 $m$ 个力度,第 $i$ 个力度能弹出 $D_i$ 节点的子树中,音高在$ [L_i,R_i]$ 中的任意一个音符。
为了乐曲的和谐,Arietta 最多会弹奏第 $i$ 个力度 $T_i$ 次。
Arietta 想知道她最多能弹出多少个音符。
输入格式
输入共 m + 3 行。
第一行两个整数 n, m ,意义如题目所述。
第二行 n - 1 个整数 $P_i$ ,表示节点$ i ( i = 2 . . . n ) $的父亲节点的编号。
第三行 n 个整数 $H_i$ 。
接下来的 m 行,每行四个整数 $L_i,R_i,D,T_i$
输出格式
输出一个整数表示 Arietta 最多能弹奏多少音符。
样例输入
5 2
1 1 2 2
5 3 2 4 1
1 3 2 1
3 5 1 4
样例输出
4
数据范围与约定
对于 100% 的数据,$1 ≤ n, m ≤ 10000$ 。
对于所有数据$1<=H_i,T_i,P_i<=N,1<=L_i<=R_i<=N$
这个题容易发现就是一个简单的网络流,每次向子树中权值在$[L_i,R_i]$中的点连边,然后每个点只能用一次,求一个最大流。但是直接上边数的规模是$O(n^2)$级别的。肯定是不行的。
考虑优化,由于要求子树中权值在$[L_i,R_i]$中的点,启发我们想到建立线段树,然后进一步的考虑主席树。
我们在每个节点维护一颗主席树,这颗主席树的叶子节点连到该点子树中的对应权值的点,然后这样向$[L_i,R_i]$连边就只需要在主席树上向对应区间的点连边了,这样的边最多有$\log n$条。然后主席树上每个点往上一个版本对应点连边,同时向新建的儿子连边.
但是需要考虑如何得到每个点的主席树,这里考虑用轻重链剖分的思想,每个点的主席树直接继承重儿子的,然后将其他轻儿子子树中的点暴力插入进去。
考虑这样的时间复杂度,由于每个点往上最多经过$\log n$条重链,因此每个点最多被暴力添加$\log n$次。因此时空复杂度都是$O(n\log^2 n)$,容易发现边的规模也是$O(n\log^2n)$的。
但是还需要注意一个问题,就是每次构建主席树的时候,可以打一个时间标记,标记每个点是何时被新建的,如果当前在主席树中访问到的点已经是这次构建中新建的点了,就不用再新建节点了。能够少添加很多节点和边,省下时间和空间。
这样做实测空间消耗是$23M$左右,另外疑似这题基础的SAP过不了,需要bfs预处理来优化。
另外,这题也可以用线段树合并做,思路差不多,每次直接将儿子节点的线段树拿来合并得到当前节点的线段树即可。复杂度是一样的,但是需要注意细节,实现的好的话空间能到$20M$以下,时间好像差不多。
代码:
1 |
|