mr_dot_convict

462-D-Appleman-and-tree-codeforces-mr.convict

Jul 7th, 2019
95
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.96 KB | None | 0 0
  1. /*author* Priyanshu Shrivastav (from IIT Palakkad) *
  2.  * *_ __ ___  _ ______ ___  _ ____   ___  ___| |_  *
  3.  * | '_ ` _ \| '__/ __/ _ \| '_ \ \ / / |/ __| __| *
  4.  * | | | | | | | | (_| (_) | | | \ V /| | (__| |_  *
  5.  * |_| |_| |_|_|(_)___\___/|_| |_|\_/ |_|\___|\__| *
  6. When I wrote this, only God and I understood what I was doing
  7.  ** * * * * * * * Now, only God knows * * * * * * */
  8. // dp on no. of sets (what kind of sets allowed? a set of connected vertices that either
  9. // [contains one black vertex and/or some white vertices]
  10. // or [contains all white vertices including root of the subtree]
  11. //
  12. // in[u] := no. of sets possible in subtree of u such
  13. // that vertex u is already covered in some set with one black vertex
  14. //
  15. // out[u] := no. of sets possible in subtree of u such
  16. // that vertex u is NOT already covered in some set with one black vertex
  17. //
  18. // let u be the parent and vi be the childs of u
  19. //
  20. // if u is black, in[u] --> either u has to be in seperate set
  21. // or it can contain white vertices which were not yet included in some set which has one black vertex
  22. //
  23. // therefore in[u] = (in[v1] + out[v1]) * (in[v2] + out[v2]) * (...) * ...
  24. // and out[u] = 0 (not possible, how can a black vertex not be already covered)
  25. //
  26. // if u is white,
  27. // out[u] --> u is not covered in any set with one black vertex, so has two options
  28. // either go with with white child vertices which are not covered yet or go alone
  29. // therefore out[u] = (in[v1] + out[v1]) * (in[v2] + out[v2]) * (...) * ...
  30. // and in[u] = chose one of the child that is already covered and go with that set (all the
  31. // remaining white not covered child sets will also go in that set)
  32. // hence in[u] = sum over i{(in[vi] * {mul of j(in[vj] + out[vj]), such that j != i}
  33. //
  34. // NOTE : the last recurrence can be done efficiently by finding the complete prod
  35. // (which is already out[u] and multiplying by mod_inv((in[vi] + out[vi]), MOD) * in[vi]
  36.  
  37. #include         <bits/stdc++.h>
  38. using namespace std;
  39. #ifndef CONVICTION
  40. #pragma GCC      optimize ("Ofast")
  41. #pragma GCC      optimize ("unroll-loops")
  42. #pragma GCC      target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
  43. #endif
  44.  
  45. #define IOS      ios_base::sync_with_stdio(false); cin.tie (nullptr)
  46. #define PREC     cout.precision (10); cout << fixed
  47. #define bg(x)    " [ " << #x << " : " << (x) << " ] "
  48. #define x        first
  49. #define y        second
  50. using ll = long long;
  51. using ff = long double;
  52. using pii = pair<int,int>;
  53.  
  54. #define debug(args...) \
  55. { \
  56. /* WARNING : do NOT compile this debug func calls with following flags: // \
  57.  * // -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC -D_FORTIFY_SOURCE=2*/ \
  58.    string _s = #args; replace(_s.begin(), _s.end(), ',', ' ');\
  59.    stringstream _ss(_s); \
  60.    istream_iterator<string> _it(_ss); err(_it, args); \
  61. }
  62. void err(istream_iterator<string> it)
  63. {
  64.    it->empty(); cerr << " (Line : " << __LINE__ << ")" << '\n';
  65. }
  66. template<typename T, typename... Args>
  67. void err(istream_iterator<string> it, T a, Args... args)
  68. {
  69.     cerr << fixed << setprecision(15)
  70.       << " [ " <<  *it << " : " << a  << " ] "<< ' ';
  71.     err(++it, args...);
  72. }
  73.  
  74. const int N = (int)1e5 + 10;
  75. const int MOD = (int)1e9 + 7;
  76. int n;
  77. int col[N]; // 0 for white and 1 for black
  78. int in[N], out[N];
  79. vector <vector<int>> adj;
  80.  
  81. inline int add (int a, int b)
  82. {
  83.    return (a + b)%MOD;
  84. }
  85. inline int mul (int a, int b)
  86. {
  87.    return int(1ll*a*b % MOD);
  88. }
  89.  
  90. inline int mul_inv (int a)
  91. {
  92.    // res = a ^ p-2
  93.    int p = MOD - 2;
  94.    int res = 1;
  95.    while (p)
  96.    {
  97.       if (p & 1)
  98.          res = mul(res, a);
  99.       a = mul(a, a);
  100.       p >>= 1;
  101.    }
  102.    return res;
  103. }
  104.  
  105. void root_at(int u, int pr, vector <bool>&vis)
  106. {
  107.    vis[u] = true;
  108.    for (auto it = adj[u].begin(); it != adj[u].end(); ++it) {
  109.       if (*it == pr) {
  110.          adj[u].erase(it);
  111.          break;
  112.       }
  113.    }
  114.    for (int v : adj[u]) {
  115.       if (!vis[v]) root_at(v, u, vis);
  116.    }
  117. }
  118.  
  119. void dfs(int u, vector <bool> &vis)
  120. {
  121.    vis[u] = true;
  122.    for (int v : adj[u])
  123.       if (!vis[v]) dfs(v, vis);
  124.  
  125.    if (col[u]) { // black
  126.       in[u] = 1, out[u] = 0;
  127.       for (int v : adj[u])
  128.          in[u] = mul(in[u], add(in[v], out[v]));
  129.    }
  130.    else { // white
  131.       in[u] = 0, out[u] = 1;
  132.  
  133.       for (int v : adj[u])
  134.          out[u] = mul(out[u], add(in[v], out[v]));
  135.  
  136.       int prod = 1;
  137.       for (int v : adj[u])
  138.          prod = mul(prod, add(in[v], out[v]));
  139.  
  140.       for (int v : adj[u])
  141.          in[u] = add(in[u], mul(in[v], mul(prod, mul_inv(add(out[v], in[v])))));
  142.    }
  143. }
  144.  
  145. void solve()
  146. {
  147.    vector <bool> vis(n, false);
  148.    root_at(0, -1, vis);
  149.  
  150.    vis.assign(n, false);
  151.    dfs(0, vis);
  152.  
  153.    cout << in[0] << '\n';
  154. }
  155.  
  156. void read()
  157. {
  158.    cin >> n;
  159.    adj.assign(n, vector <int>());
  160.    for (int i = 1; i < n; ++i) {
  161.       int p; cin >> p;
  162.       adj[i].push_back(p);
  163.       adj[p].push_back(i);
  164.    }
  165.    for (int i = 0; i < n; ++i)
  166.       cin >> col[i];
  167. }
  168.  
  169. signed main()
  170. {
  171.    IOS; PREC;
  172.    read(), solve();
  173.  
  174.    return EXIT_SUCCESS;
  175. }
Add Comment
Please, Sign In to add comment