raghuvanshraj

Awesome Code

Apr 9th, 2020
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.51 KB | None | 0 0
  1. /**
  2.  *    author:   raghuvanshraj
  3.  *    created:  09.04.2020 03:36:58 PM
  4. **/
  5. #include <bits/stdc++.h>
  6. #include <ext/pb_ds/assoc_container.hpp>
  7.  
  8. #define MOD 1000000007
  9.  
  10. #define SET_ARR(arr,n,val) for (int i = 0; i < n; ++i) arr[i] = val
  11. #define SET_ARR2D(arr,n,m,val) for (int i = 0; i < n; ++i) for (int j = 0; j < m; ++j) arr[i][j] = val
  12. #define INPUT_ARR(arr,n) for (int i = 0; i < n; ++i) cin >> arr[i];
  13. #define INPUT_ARR2D(arr,n,m) for (int i = 0; i < n; ++i) for (int j = 0; j < m; ++j) cin >> arr[i][j];
  14. #define PRINT_ARR(arr,n) for (int i = 0; i < n; ++i) cout << arr[i] << ' '; cout << endl
  15. #define PRINT_ARR2D(arr,n,m) for (int i = 0; i < n; ++i) { for (int j = 0; j < m; ++j) cout << arr[i][j] << ' '; cout << endl; }
  16.  
  17. #define ALL(v) v.begin(), v.end()
  18. #define RALL(v) v.rbegin(), v.rend()
  19.  
  20. using namespace std;
  21. using namespace __gnu_pbds;
  22.  
  23. typedef long long ll;
  24. typedef unsigned long long ull;
  25. typedef long double ld;
  26.  
  27. template <typename T>
  28. using indexed_set = tree<T, null_type,less<T>, rb_tree_tag, tree_order_statistics_node_update>;
  29.  
  30. template <typename T>
  31. using max_heap = priority_queue<T>;
  32.  
  33. template <typename T>
  34. using min_heap = priority_queue<T, vector<T>, greater<T>>;
  35.  
  36. template <
  37.     typename T,
  38.     typename = typename enable_if<is_arithmetic<T>::value, T>::type,
  39.     typename U,
  40.     typename = typename enable_if<is_arithmetic<U>::value, U>::type
  41. >
  42. pair<T,U> operator+(const pair<T,U> &a, const pair<T,U> &b) {
  43.     return {a.first + b.first, a.second + b.second};
  44. }
  45.  
  46. template <
  47.     typename T,
  48.     typename = typename enable_if<is_arithmetic<T>::value, T>::type,
  49.     typename U,
  50.     typename = typename enable_if<is_arithmetic<U>::value, U>::type
  51. >
  52. pair<T,U> operator-(const pair<T,U> &a, const pair<T,U> &b) {
  53.     return {a.first - b.first, a.second - b.second};
  54. }
  55.  
  56. template <
  57.     typename T,
  58.     typename = typename enable_if<is_arithmetic<T>::value, T>::type,
  59.     typename U,
  60.     typename = typename enable_if<is_arithmetic<U>::value, U>::type,
  61.     typename V,
  62.     typename = typename enable_if<is_arithmetic<V>::value, V>::type
  63. >
  64. pair<T,U> operator*(const V &a, const pair<T,U> &b) {
  65.     return {a * b.first, a * b.second};
  66. }
  67.  
  68. long solve(vector<vector<int>> &adj_list, vector<vector<int>> &dp, int u, int p, int col_u, int col_p) {
  69.     if (adj_list[u].size() == 1 and p != -1) {
  70.         return col_p == col_u;
  71.     }
  72.  
  73.     if (dp[u][col_u == col_p] != -1) {
  74.         return dp[u][col_u ==col_p];
  75.     }
  76.  
  77.     long ans = 1;
  78.     long red_inv = 1;
  79.     long black_inv = 1;
  80.     for (int v : adj_list[u]) {
  81.         if (v != p) {
  82.             long vr = solve(adj_list, dp, v, u, 0, col_u);
  83.             long vb = solve(adj_list, dp, v, u, 1, col_u);
  84.  
  85.             ans = (ans * ((vr+vb) % MOD)) % MOD;
  86.             red_inv = (red_inv * vr) % MOD;
  87.             black_inv = (black_inv * vb) % MOD;
  88.         }
  89.     }
  90.  
  91.     if (p == -1) {
  92.         if (col_u == 0) {
  93.             ans = (ans - black_inv + MOD) % MOD;
  94.         } else {
  95.             ans = (ans - red_inv + MOD) % MOD;
  96.         }
  97.     }
  98.  
  99.     if (col_u != col_p and p != -1) {
  100.         if (col_p == 0) {
  101.             ans = (ans - red_inv + MOD) % MOD;
  102.         } else {
  103.             ans = (ans - black_inv + MOD) % MOD;
  104.         }
  105.     }
  106.  
  107.     dp[u][col_u == col_p] = ans;
  108.  
  109.     return ans;
  110. }
  111.  
  112. int main(int argc, char const *argv[]) {
  113.     ios::sync_with_stdio(false);
  114.     cin.tie(0);
  115.    
  116.     int n;
  117.     cin >> n;
  118.     int m = n-1;
  119.     vector<vector<int>> adj_list(n);
  120.     while (m--) {
  121.         int u,v;
  122.         cin >> u >> v;
  123.         u--;
  124.         v--;
  125.  
  126.         adj_list[u].push_back(v);
  127.         adj_list[v].push_back(u);
  128.     }
  129.  
  130.     vector<vector<int>> dp(n, vector<int>(2,-1));
  131.     long ans1 = solve(adj_list, dp, 0, -1, 0, 0);
  132.     long ans2 = solve(adj_list, dp, 0, -1, 1, 0);
  133.  
  134.     cout << (ans1 + ans2) % MOD;
  135.    
  136.     return 0;
  137. }
Add Comment
Please, Sign In to add comment