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).
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 a single integer — the number of ways to split the tree modulo 1000000007 (109 + 7).
3 0 0 0 1 1
2
6 0 1 1 0 4 1 1 0 0 1 0
1
10 0 1 2 1 4 4 4 0 8 0 0 0 1 0 1 1 0 0 1
27
题目大意:给你一颗树,树上的点有黑白2种颜色,现在要砍掉k个树边使得剩下的子树都有恰好一个黑点,问有多少种方案?
解题思路:dp[x][0]表示以x为根的子树,根节点没有和黑点联通的方案数
dp[x][1]表示以x为根的子树,根节点恰和一个黑点联通的方案数
对于一个根节点x的儿子y,
如果x是黑点,则dp[x][1]=dp[x][1]*(dp[y][0]+dp[y][1]),(前面已经保证有黑点,y有没有黑点无所谓)
否则,dp[x][1]=dp[x][1]*(dp[y][0]+dp[y][1])+dp[x][0]*dp[y][1](比上面多了前面没有黑点,y有黑点的情况)
dp[x][0]=dp[x][0]*(dp[y][0]+dp[y][1])(前面没有,因为x是白点,y有没有黑点无所谓)
#include <iostream>
#include <cstdio>
#include <vector>
#define mod 1000000007
#define ll long long
using namespace std;
int n;
vector<int> G[100010];
int c[100010];
ll dp[100010][2];
void init(){
for(int i=0;i<100010;i++) G[i].clear();
}
void read(){
int x;
for(int i=0;i<n-1;i++){
scanf("%d",&x);
G[x].push_back(i+1);
}
for(int i=0;i<n;i++) scanf("%d",&c[i]);
}
void dfs(int x,int fa){
int nn=G[x].size();
if(c[x]==0) dp[x][0]=1,dp[x][1]=0;
else dp[x][0]=0,dp[x][1]=1;
for(int i=0;i<nn;i++){
int v=G[x][i];
if(v!=fa){
dfs(v,x);
if(c[x]==0){
dp[x][1]=(dp[x][1]*(dp[v][0]+dp[v][1])%mod+dp[x][0]*dp[v][1]%mod)%mod;
dp[x][0]=dp[x][0]*(dp[v][0]+dp[v][1])%mod;
}else{
dp[x][1]=dp[x][1]*(dp[v][0]+dp[v][1])%mod;
}
}
}
}
void solve(){
dfs(0,-1);
printf("%I64d\n",dp[0][1]);
}
int main(){
while(~scanf("%d",&n)){
init();
read();
solve();
}
return 0;
}