Tuesday, 5 January 2016

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