Advertisement
matheus_monteiro

Jumping Path

Dec 9th, 2021
104
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.44 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. #define int long long
  5.  
  6. #define _ << " , " <<
  7. #define bug(x) cout << #x << "  >>>>>>>  " << x << endl;
  8. #define fastio ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
  9.  
  10. #define ii pair<int, int>
  11. #define fi first
  12. #define se second
  13.  
  14. const int MAX = 1000100;
  15. const int MOD = 11092019;
  16. #define esq ((node << 1))
  17. #define dir (((node << 1) | 1))
  18. #define mid (((start + end) >> 1))
  19.  
  20. ii tree[4 * MAX];
  21.  
  22. ii merge(ii a, ii b) {
  23.     ii c = { max(a.fi, b.fi), 0};
  24.     if(c.fi == a.fi) c.se = (c.se + a.se) % MOD;
  25.     if(c.fi == b.fi) c.se = (c.se + b.se) % MOD;
  26.     return c;
  27. }  
  28.  
  29. ii query(int node, int start, int end, int l, int r) {
  30.     if(l > end or r < start) return {-0x3f3f3f3f, 0};
  31.     if(l <= start and end <= r) return tree[node];
  32.     ii q1 = query(esq, start, mid, l, r);
  33.     ii q2 = query(dir, mid + 1, end, l, r);
  34.     return merge(q1, q2);
  35. }
  36.  
  37. void update(int node, int start, int end, int idx, ii value) {
  38.     if(start == end)
  39.         tree[node] = value;
  40.     else {
  41.         if(start <= idx and idx <= mid) update(esq, start, mid, idx, value);
  42.         else update(dir, mid + 1, end, idx, value);
  43.         tree[node] = merge(tree[esq], tree[dir]);
  44.     }
  45. }
  46.  
  47. vector<int> G[MAX];
  48. int label[MAX];
  49.  
  50. int lis(int v) {
  51.     ii ant = query(1, 0, MAX - 1, label[v], label[v]);
  52.     ii mx = query(1, 0, MAX - 1, 0, label[v]);
  53.     update(1, 0, MAX - 1, label[v], ii(mx.fi + 1, mx.se));
  54.     int l = tree[1].fi;
  55.     for(int &u : G[v])
  56.         l = max(l, lis(u));
  57.     update(1, 0, MAX - 1, label[v], ant);
  58.     return l;
  59. }
  60.  
  61. int count(int v, int lis) {
  62.     ii ant = query(1, 0, MAX - 1, label[v], label[v]);
  63.     ii mx = query(1, 0, MAX - 1, 0, label[v]);
  64.     int cnt = 0;
  65.     bool undo_op = true;
  66.     if(mx.fi + 1 == lis) {
  67.         cnt = mx.se;
  68.         mx = {-1, 0};
  69.         undo_op = false;
  70.     }
  71.     update(1, 0, MAX - 1, label[v], ii(mx.fi + 1, mx.se));
  72.     for(int &u : G[v])
  73.         cnt = (cnt + count(u, lis)) % MOD;
  74.     if(undo_op)
  75.         update(1, 0, MAX - 1, label[v], ant);
  76.     return cnt;
  77. }
  78.  
  79. int32_t main() {
  80.     fastio;
  81.  
  82.     int n;
  83.     cin >> n;
  84.     for(int i = 1; i <= n; ++i) cin >> label[i], label[i]++;
  85.  
  86.     for(int i = 2; i <= n; ++i) {
  87.         int j;
  88.         cin >> j;
  89.         G[j].push_back(i);
  90.     }
  91.  
  92.     update(1, 0, MAX - 1, 0, ii(0, 1));
  93.    
  94.     int l = lis(1);
  95.     int cnt = count(1, l);
  96.  
  97.     cout << l << ' ' << cnt << '\n';
  98.  
  99.     return 0;
  100. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement