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;
}