# 代码的搬运工
先是定义动态规划集合
f[i][0], f[i][1] 分别代表i为根的子树种无白和有一白的数量
如果i是白色的,f[i][0] = 0;
f[i][1] = TT(连乘)( f[k][0](不断开) + f[k][1](断开有白));
i是黑色,f[i][0] = TT(连乘)( f[k][0](不断开) + f[k][1](断开有白) );
f[i][1] = E(连加) (f[j][1] * TT(k != j) ( f[k][0](不断开) + f[k][1](断开有白)));
#include<bits/stdc++.h>
using namespace std;
const int N = 100010, mod = 1e9 + 7;
typedef long long LL;
int color[N];
int f[N][2];
int h[N],e[N],ne[N],idx;
int q[N],mul[N],l[N], r[N];
void add(int a,int b){
e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}
void dfs(int u){
for(int i = h[u]; ~i; i = ne[i]) dfs(e[i]);
if(color[u] == 0){
f[u][1] = 1;
for(int i = h[u]; ~i;i = ne[i]) f[u][1] = (LL)f[u][1] * (f[e[i]][0] + f[e[i]][1]) % mod;
}else{
f[u][0] = 1;
for(int i = h[u]; ~i;i = ne[i]) f[u][0] = (LL)f[u][0] * (f[e[i]][0] + f[e[i]][1]) % mod;
int k = 0;
for(int i = h[u]; ~i;i = ne[i]) q[++k] = e[i];//把紫薯全存进去
//mul[q[1]] = 1;
for(int i = 1, p= 1; i <= k;i++) //mul[q[i]] = (LL)mul[q[i-1]] * (f[q[i-1]][0] + f[q[i-1]][1]) % mod;
{
mul[i] = p;
p = (LL)p * (f[q[i]][0] + f[q[i]][1]) % mod;
}
for(int i = k,p = 1; i >=1;i--) {
mul[i] =(LL)mul[i] * p %mod;
p = (LL) p* (f[q[i]][0] + f[q[i]][1]) % mod;
}
// l[0] = r[k+1] = 1;
// for(int i = 1;i <= k;i++) l[i] = (LL)l[i-1] * (f[q[i]][0] +f[q[i]][1])%mod;
// for(int i = k;i >= 1;i--) r[i] = (LL)r[i+1] * (f[q[i]][0] +f[q[i]][1])%mod;
f[u][1] = 0;
for(int i = 1; i <= k; i++ ){
f[u][1] = (f[u][1] + (LL) f[q[i]][1] * mul[i] )% mod;
//f[u][1] = (f[u][1] +(LL)l[i - 1] * r[i+1]% mod * f[q[i]][1] )% mod;
}
}
}
int main(){
int n;
cin >> n;
memset(h, -1, sizeof h);
for(int i = 1; i < n;i++){
int k;
cin >> k;
add(k,i);//k是根
}
for(int i = 0;i < n;i++) cin >> color[i];
dfs(0);
cout << f[0][1];
return 0;
}