【CodeForces - 1153D】Serval and Rooted Tree(树形dp)

题干:

Now Serval is a junior high school student in Japari Middle School, and he is still thrilled on math as before.

As a talented boy in mathematics, he likes to play with numbers. This time, he wants to play with numbers on a rooted tree.

A tree is a connected graph without cycles. A rooted tree has a special vertex called the root. A parent of a node vv is the last different from vv vertex on the path from the root to the vertex vv. Children of vertex vv are all nodes for which vvis the parent. A vertex is a leaf if it has no children.

The rooted tree Serval owns has nn nodes, node 11 is the root. Serval will write some numbers into all nodes of the tree. However, there are some restrictions. Each of the nodes except leaves has an operation maxmax or minmin written in it, indicating that the number in this node should be equal to the maximum or minimum of all the numbers in its sons, respectively.

Assume that there are kk leaves in the tree. Serval wants to put integers 1,2,…,k1,2,…,kto the kk leaves (each number should be used exactly once). He loves large numbers, so he wants to maximize the number in the root. As his best friend, can you help him?

Input

The first line contains an integer nn (2≤n≤3⋅1052≤n≤3⋅105), the size of the tree.

The second line contains nn integers, the ii-th of them represents the operation in the node ii. 00 represents minmin and 11 represents maxmax. If the node is a leaf, there is still a number of 00 or 11, but you can ignore it.

The third line contains n−1n−1 integers f2,f3,…,fnf2,f3,…,fn (1≤fi≤i−11≤fi≤i−1), where fifirepresents the parent of the node ii.

Output

Output one integer — the maximum possible number in the root of the tree.

Examples

Input

6
1 0 1 1 0 1
1 2 2 2 2

Output

1

Input

5
1 0 1 0 1
1 1 1 1

Output

4

Input

8
1 0 0 1 0 1 1 0
1 1 2 2 3 3 3

Output

4

Input

9
1 1 0 0 1 0 1 0 1
1 1 2 2 3 3 4 4

Output

5

Note

Pictures below explain the examples. The numbers written in the middle of the nodes are their indices, and the numbers written on the top are the numbers written in the nodes.

In the first example, no matter how you arrange the numbers, the answer is 11.

In the second example, no matter how you arrange the numbers, the answer is 44.

In the third example, one of the best solution to achieve 44 is to arrange 44 and 55 to nodes 44 and 55.

In the fourth example, the best solution is to arrange 55 to node 55.

题目大意:

   n个节点的一棵树,1号节点是根节点。每个点有属性0或1,分别代表可以获得子树的最小权值  子树的最大权值。假设有k个叶子结点,那么这k个节点的权值为1~k,自由分配。问你根节点可以获得的最大权值是多少?

解题报告:

   对于每棵子树来说,根节点的值越大越好,因为有操作符的存在,无法准确求出根结点的值,但可以求出根节点的值在这个子树所有叶节点的值中大小排第几。这样设定状态比较方便合并子问题。

用dp[i]表示以 i 为根节点的子树中,根节点 i 所得到的在子树中排名的最大值。

对于每一种情况,我们都从小到大分配权值,这是为了方便简化思考。

如果属性值为1,考虑到最终只能传一个值到根节点,所以我们枚举是从第j棵子树的值传递上来的。这样我们肯定要让其他叶子结点都是最小值,所以我们的dp[cur]就是max(sum[cur]-sum[v] + dp[v]);

如果属性值为0,那么我们先让权值从小到大均匀分配,每个子节点分配dp[i]-1个叶子,然后任选一个点当做往上传的点,这样dp[cur]=∑(dp[i]-1) + 1;

AC代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define F first
#define S second
#define ll long long
#define pb push_back
#define pm make_pair
using namespace std;
typedef pair<int,int> PII;
const int MAX = 3e5 + 5;
int n;
int sum[MAX],dp[MAX],val[MAX];
vector<int> vv[MAX];
void dfs(int cur,int rt) {
	dp[cur]=1;
	if(vv[cur].size() == 0) {
		sum[cur] = 1;//叶子结点的数量 
		return ;
	}
	int up = vv[cur].size(),tmp=0;
	for(int i = 0; i<up; i++) {
		int v = vv[cur][i];
		dfs(v,cur);
		sum[cur] += sum[v];
	}
	if(val[cur] == 1) {
		for(int i = 0; i<up; i++) {
			int v = vv[cur][i];
			dp[cur] = max(dp[cur],sum[cur]-sum[v]+dp[v]);
		}
	}
	else {
		for(int i = 0; i<up; i++) {
			int v = vv[cur][i];
			tmp += sum[v]-dp[v];
		}
		dp[cur] = sum[cur]-tmp-up+1;
	}
}
int main()
{
	cin>>n;
	for(int i = 1; i<=n; i++) scanf("%d",val+i);
	for(int tmp,i = 2; i<=n; i++) scanf("%d",&tmp),vv[tmp].pb(i);
	dfs(1,-1);
	printf("%d\n",dp[1]);

	return 0 ;
}

是我太菜了,,去重修dp了、、 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值