题目描述
给定一棵n个节点的有根树,编号依次为1到n,其中1号点为根节点。每个点有一个权值v_i。
你需要将这棵树转化成一个大根堆。确切地说,你需要选择尽可能多的节点,满足大根堆的性质:对于任意两个点i,j,如果i在树上是j的祖先,那么v_i>v_j。
请计算可选的最多的点数,注意这些点不必形成这棵树的一个连通子树。
输入格式
第一行包含一个正整数n(1<=n<=200000),表示节点的个数。
接下来n行,每行两个整数v_i,p_i(0<=v_i<=10^9,1<=p_i<i,p_1=0),表示每个节点的权值与父亲。
输出格式
输出一行一个正整数,即最多的点数。
样例
样例输入
6
3 0
1 1
2 1
3 1
4 1
5 1
样例输出
5
私货:
摆了,有时间在详细写。
思路历程:
1.最开始想最暴力的方法,我先把树建出来,然后对每一个点固定为树根,我暴力搜它的子树,pushup再pushup,存进去我的数组,赢!
今天你赢赢赢,明天我输光光
但是专题的名字叫线段树合并啊
2.或许dp可以解决这个问题,我还是固定一个点作为树根,但是我用\(f_u,_i\)表示以u为树根的子树里的节点权值小于i的个数。\(i\)<=\(v_u\).
我们用\(size_u\)表示u的子节点大小。
就有了转移方程:
………………
………………
推出来了吗?
我没推出来呢()
欸要不你悄悄把转移方程洛谷V我,要不然这个博客就结束了()
…………
ok现在我们得到了转移方程,(感\(K_8He\)老师的博客对这个fw的大力支持)
\(1....\)\(f_u,_i=\sum\limits_{size_u}^{}\) \(f_u,_i\) , \(i<=v_u\)
\(2....\)\(f_u,_i=max(\sum\limits_{size_u}^{}f_u,_i,\sum\limits_{size_u}^{}\) \(f_u,_{i+1}\)-1) , \(i>=v_u\)
贴贴(链接)
ps:没有贴错人也没有贴错题,详见下()
再贴
ok现在不会了去看题解了拜拜
先这样吧一会在写代码,我转移方程应该是错的()回来再改