제출 #1310186

#제출 시각아이디문제언어결과실행 시간메모리
1310186nikileZoltan (COCI16_zoltan)C++20
35 / 140
1097 ms19328 KiB
#include <bits/stdc++.h> using namespace std; using ll = long long; #define all(x) (x).begin(), (x).end() #define rall(x) (x).rbegin(), (x).rend() #ifndef nikile #pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt") #pragma GCC optimize("O3,unroll-loops") #endif const int mod = 1e9 + 7; int add(int a, int b) { if (a + b >= mod) { return a + b - mod; } else { return a + b; } } int sub(int a, int b) { if (a < b) { return a - b + mod; } else { return a - b; } } int mul(int a, int b) { return 1ll * a * b % mod; } struct node { int val = 0, cnt = 1; node(int a, int b) { val = a; cnt = b; } node() { val = 0; cnt = 1; } }; struct segtree { vector<node> t; segtree(int n) { t.resize(4 * n); } node merge(node &a, node &b) { node m = a; if (a.val == 0) { return b; } if (b.val == 0) { return a; } if (a.val == b.val) { m.cnt = add(a.cnt, b.cnt); } else if (a.val < b.val) { m = b; } return m; } void upd(int lx, int rx, int x, int i, node v) { if (lx + 1 == rx) { t[x] = v; return; } int m = (lx + rx) / 2; if (i < m) { upd(lx, m, 2 * x + 1, i, v); } else { upd(m, rx, 2 * x + 2, i, v); } t[x] = merge(t[2 * x + 1], t[2 * x + 2]); } node get(int lx, int rx, int x, int l, int r) { if (lx >= r || l >= rx) { return {0, 1}; } if (l <= lx && rx <= r) { return t[x]; } int m = (lx + rx) / 2; node A = get(lx, m, 2 * x + 1, l, r); node B = get(m, rx, 2 * x + 2, l, r); return merge(A, B); } }; void solve() { int n; cin >> n; vector<int> a(n), pw(n + 1, 1); vector<pair<int, int>> s(n); for (int i = 0; i < n; i++) { cin >> a[i]; s[i].first = a[i]; s[i].second = i; pw[i + 1] = mul(pw[i], 2); } sort(all(s)); segtree t1(n), t2(n); vector<int> dp1(n), cnt1(n), dp2(n), cnt2(n); for (int i = n - 1; i >= 0; i--) { int it = lower_bound(all(s), make_pair(a[i], i)) - s.begin(); int pos = upper_bound(all(s), make_pair(a[i], n)) - s.begin(); node now = t1.get(0, n, 0, pos, n); dp1[i] = now.val + 1; cnt1[i] = now.cnt; t1.upd(0, n, 0, it, node(dp1[i], cnt1[i])); pos = lower_bound(all(s), make_pair(a[i], 0)) - s.begin() - 1; now = t2.get(0, n, 0, 0, it); dp2[i] = now.val + 1; cnt2[i] = now.cnt; t2.upd(0, n, 0, it, node(dp2[i], cnt2[i])); } int ans = 0; for (int i = 0; i < n; i++) { int mx = 0; for (int j = 0; j < n; j++) { if (a[i] > a[j]) { mx = max(mx, dp2[j]); } } ans = max(ans, mx + dp1[i]); } int cnt = 0, x = *max_element(all(dp1)); for (int i = 0; i < n; i++) { if (dp1[i] != x) continue; for (int j = 0; j < n; j++) { if (a[i] > a[j] && dp1[i] + dp2[j] == ans) { cnt = add(cnt, mul(pw[n - ans], mul(cnt1[i], cnt2[j]))); } } if (dp1[i] == ans) { cnt = add(cnt, mul(pw[n - ans], cnt1[i])); } } cout << ans << " " << cnt << "\n"; } signed main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); #ifdef nikile freopen("input.txt", "r", stdin); #endif solve(); return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...