CodeForces 461 B.Appleman and Tree(树形dp)

B.Appleman and Tree

Appleman has a tree with n vertices. Some of the vertices (at least one) are colored black and other vertices are colored white.

Consider a set consisting of k (0 ≤ k < n) edges of Appleman’s tree. If Appleman deletes these edges from the tree, then it will split into (k + 1) parts. Note, that each part will be a tree with colored vertices.

Now Appleman wonders, what is the number of sets splitting the tree in such a way that each resulting part will have exactly one black vertex? Find this number modulo 1000000007 (109 + 7).

Input

The first line contains an integer n (2  ≤ n ≤ 105) — the number of tree vertices.

The second line contains the description of the tree: n - 1 integers p0, p1, …, pn - 2 (0 ≤ pi ≤ i). Where pi means that there is an edge connecting vertex (i + 1) of the tree and vertex pi. Consider tree vertices are numbered from 0 to n - 1.

The third line contains the description of the colors of the vertices: n integers x0, x1, …, xn - 1 (xi is either 0 or 1). If xi is equal to 1, vertex i is colored black. Otherwise, vertex i is colored white.

Output

Output a single integer — the number of ways to split the tree modulo 1000000007 (109 + 7).

Examples

Input

3
0 0
0 1 1

Output

2

Input

6
0 1 1 0 4
1 1 0 0 1 0

Output

1

Input

10
0 1 2 1 4 4 4 0 8
0 0 0 1 0 1 1 0 0 1

Output

27

思路:

d[i][0/1]表示点i所在连通块是否有黑色点的方案数

树形dp自下而上的过程中,对于每条边

d[x][1]:
1.x黑色v白色连接:d[x][1]*d[v][0]
2.x白色v黑色连接:d[x][0]*d[v][1]
3.x黑色v黑色断开:d[x][1]*d[v][1]
合并之后就是d[x][1]=d[x][1]*(d[v][0]+d[v][1])+d[x][0]*d[v][1];

d[x][0]:
1.x白色v白色连接:d[x][0]*d[v][0]
2.x白色v黑色断开:d[x][0]*d[v][1]
合并之后就是d[x][0]=d[x][0]*(d[v][0]+d[v][1]);

code:

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxm=1e5+5;
const int mod=1e9+7;
vector<int>g[maxm];
int d[maxm][2];//d[i][0/1]表示点i所在连通块是否有黑色点的方案数
int c[maxm];
int n;
void dfs(int x){
    if(c[x])d[x][1]=1;
    else d[x][0]=1;
    for(int v:g[x]){
        dfs(v);
        /*
            d[x][1]:
            1.x黑色v白色连接:d[x][1]*d[v][0]
            2.x白色v黑色连接:d[x][0]*d[v][1]
            3.x黑色v黑色断开:d[x][1]*d[v][1]
            合并之后就是d[x][1]=d[x][1]*(d[v][0]+d[v][1])+d[x][0]*d[v][1];

            d[x][0]:
            1.x白色v白色连接:d[x][0]*d[v][0]
            2.x白色v黑色断开:d[x][0]*d[v][1]
            合并之后就是d[x][0]=d[x][0]*(d[v][0]+d[v][1]);

            计算过程取模
        */
        d[x][1]=(d[x][1]*(d[v][1]+d[v][0])%mod+d[x][0]*d[v][1]%mod)%mod;
        d[x][0]=d[x][0]*(d[v][1]+d[v][0])%mod;
    }
}
signed main(){
    cin>>n;
    for(int i=1;i<n;i++){
        int fa;
        cin>>fa;
        g[fa].push_back(i);
    }
    for(int i=0;i<n;i++){
        cin>>c[i];
    }
    dfs(0);
    cout<<d[0][1]<<endl;
    return 0;
}
发布了364 篇原创文章 · 获赞 26 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_44178736/article/details/103327926
今日推荐