Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- using namespace std;
- #define int long long
- #define _ << " , " <<
- #define bug(x) cout << #x << " >>>>>>> " << x << endl;
- #define fastio ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
- #define ii pair<int, int>
- #define fi first
- #define se second
- const int MAX = 1000100;
- const int MOD = 11092019;
- #define esq ((node << 1))
- #define dir (((node << 1) | 1))
- #define mid (((start + end) >> 1))
- ii tree[4 * MAX];
- ii merge(ii a, ii b) {
- ii c = { max(a.fi, b.fi), 0};
- if(c.fi == a.fi) c.se = (c.se + a.se) % MOD;
- if(c.fi == b.fi) c.se = (c.se + b.se) % MOD;
- return c;
- }
- ii query(int node, int start, int end, int l, int r) {
- if(l > end or r < start) return {-0x3f3f3f3f, 0};
- if(l <= start and end <= r) return tree[node];
- ii q1 = query(esq, start, mid, l, r);
- ii q2 = query(dir, mid + 1, end, l, r);
- return merge(q1, q2);
- }
- void update(int node, int start, int end, int idx, ii value) {
- if(start == end)
- tree[node] = value;
- else {
- if(start <= idx and idx <= mid) update(esq, start, mid, idx, value);
- else update(dir, mid + 1, end, idx, value);
- tree[node] = merge(tree[esq], tree[dir]);
- }
- }
- vector<int> G[MAX];
- int label[MAX];
- int lis(int v) {
- ii ant = query(1, 0, MAX - 1, label[v], label[v]);
- ii mx = query(1, 0, MAX - 1, 0, label[v]);
- update(1, 0, MAX - 1, label[v], ii(mx.fi + 1, mx.se));
- int l = tree[1].fi;
- for(int &u : G[v])
- l = max(l, lis(u));
- update(1, 0, MAX - 1, label[v], ant);
- return l;
- }
- int count(int v, int lis) {
- ii ant = query(1, 0, MAX - 1, label[v], label[v]);
- ii mx = query(1, 0, MAX - 1, 0, label[v]);
- int cnt = 0;
- bool undo_op = true;
- if(mx.fi + 1 == lis) {
- cnt = mx.se;
- mx = {-1, 0};
- undo_op = false;
- }
- update(1, 0, MAX - 1, label[v], ii(mx.fi + 1, mx.se));
- for(int &u : G[v])
- cnt = (cnt + count(u, lis)) % MOD;
- if(undo_op)
- update(1, 0, MAX - 1, label[v], ant);
- return cnt;
- }
- int32_t main() {
- fastio;
- int n;
- cin >> n;
- for(int i = 1; i <= n; ++i) cin >> label[i], label[i]++;
- for(int i = 2; i <= n; ++i) {
- int j;
- cin >> j;
- G[j].push_back(i);
- }
- update(1, 0, MAX - 1, 0, ii(0, 1));
- int l = lis(1);
- int cnt = count(1, l);
- cout << l << ' ' << cnt << '\n';
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement