f[x][0]表示与其父边相连的连通块内没有黑苹果的方案数,
f[x][1]则表示有黑苹果,
如果父边被切断,相当于没有黑苹果
初始化时,假设切掉父边,f[x][0]=1,f[x][1]=0;
递归回时转移,每递归回一个子树,f[x][1]=f[x][1]*f[v][0]+f[x][0]*f[v][1],f[x][0]=f[x][0]*f[v][0];
最后处理完每个子树时,若其为黑苹果f[x][1]=f[x][0],否则f[x][0]=f[x][0]+f[x][1](可以切掉)
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#define N 100050
#define mod 1000000007ll
using namespace std;
int n,c[N],fa[N];
long long f[N][2];
int e=1,head[N];
struct edge{
int u,v,next;
}ed[2*N];
void add(int u,int v){
ed[e].u=u;ed[e].v=v;
ed[e].next=head[u];head[u]=e++;
}
void dfs(int x){
f[x][0]=1;f[x][1]=0;
for(int i=head[x];i;i=ed[i].next){
int v=ed[i].v;
if(v==fa[x]) continue;
fa[v]=x; dfs(v);
f[x][1]=(f[x][1]*f[v][0])%mod;
f[x][1]=(f[x][1]+(f[x][0]*f[v][1])%mod)%mod;
f[x][0]=(f[x][0]*f[v][0])%mod;
}
if(c[x]) f[x][1]=f[x][0];
else f[x][0]=(f[x][0]+f[x][1])%mod;
}
int main(){
//freopen("tree.in","r",stdin);
//freopen("tree.out","w",stdout);
scanf("%d",&n);int a;
for(int i=2;i<=n;i++){
scanf("%d",&a);a++;
add(i,a); add(a,i);
}
for(int i=1;i<=n;i++)
scanf("%d",&c[i]);
dfs(1);
printf("%lld
",f[1][1]);
return 0;
}