简单的树形
DP
。记
fi,0/1
表示考虑以
i
<script type="math/tex" id="MathJax-Element-189">i</script> 为根的子树,所在的块有一个黑或没有黑结点的方案数。
转移很显然。
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long LL;
const int maxn=100005,maxe=100005,MOD=1000000007;
int n,c[maxn];
LL f[maxn][2];
int fir[maxn],nxt[maxe],son[maxe],tot;
void add(int x,int y){
son[++tot]=y; nxt[tot]=fir[x]; fir[x]=tot;
}
LL Pow(LL a,int b){
LL res=1; a%=MOD;
for(;b;b>>=1,a=a*a%MOD) if(b&1) res=(res*a)%MOD;
return res;
}
void dfs(int x){
LL all0=1;
for(int j=fir[x];j;j=nxt[j]) dfs(son[j]), (all0*=(f[son[j]][0]+f[son[j]][1])%MOD)%=MOD;
if(c[x]) f[x][1]=all0, f[x][0]=0; else{
f[x][0]=all0;
for(int j=fir[x];j;j=nxt[j]) (f[x][1]+=all0*Pow(f[son[j]][0]+f[son[j]][1],MOD-2)%MOD*f[son[j]][1]%MOD)%=MOD;
}
}
int main(){
freopen("51nod1500.in","r",stdin);
freopen("51nod1500.out","w",stdout);
scanf("%d",&n);
for(int i=2;i<=n;i++){
int x; scanf("%d",&x);
add(x+1,i);
}
for(int i=1;i<=n;i++) scanf("%d",&c[i]);
dfs(1);
printf("%d\n",f[1][1]);
return 0;
}