B. Appleman and Tree
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
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).
Sample test(s)
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
Editorial
First of all fick up the leaf condition
It should return 1 in case it is black
and 0 in case it is white
so we set the initial condition as
one =1-c[root];
zero=c[root];
Now the state of DP is
DP[v][0] = the number of ways that the subtree rooted at vertex v has no black vertex.
DP[v][1] = the number of ways that the subtree rooted at vertex v has one black vertex.
so the number of subtrees with one black node considering the root is
one=one*dp[0][v] (considering black root we attach this root to all possible subtrees with 0 black nodes)
+ one*dp[1][v] (considering black root we keep it disjoint)
+ zero*dp[1][v] (considering a white root we attach it to all the subtrees with 1 black vertex)
zero=zero*dp[1][v] (considering white vertex we attach it to all subtrees having one black vertex)
+ zero*dp[0][v] we keep this white vertex with the subtrees that has o black vertices)
answer is dp[root][1]
Here is the code
#include <bits/stdc++.h>
#define REP(a,b) for(int a=0; a<(b); ++a)
#define FWD(a,b,c) for(int a=(b); a<(c); ++a)
#define FWDS(a,b,c,d) for(int a=(b); a<(c); a+=d)
#define BCK(a,b,c) for(int a=(b); a>(c); --a)
#define x first
#define y second
#define pb push_back
#define re real()
#define im imag()
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
typedef double K;
typedef vector<int> VI;
int dx[] = {0,0,-1,1}; //1,1,-1,1};
int dy[] = {-1,1,0,0}; //1,-1,1,-1};
const int mod = 1000000007;
int n;
vector<int> sons[100010];
LL M[2][100010];
int C[100010];
void dfs(int u){
LL zero, one;
zero = 1-C[u];
one = C[u];
vector<int> ::iterator it;
for(it=sons[u].begin();it!=sons[u].end();it++)
{
int v=*it;
dfs(v);
one = (one * M[1][v] + one * M[0][v] + zero * M[1][v]) % mod;
zero = (zero * M[1][v] + zero * M[0][v]) % mod;
}
M[0][u] = zero;
M[1][u] = one;
}
int main(){
scanf("%d", &n);
FWD(i,1,n){
int p;
scanf("%d", &p);
sons[p].push_back(i);
}
FWD(i,0,n) scanf("%d", &C[i]);
dfs(0);
printf("%d\n", (int)M[1][0]);
return 0;
}
No comments:
Post a Comment