Submission #130469

#TimeUsernameProblemLanguageResultExecution timeMemory
130469forestryksZoltan (COCI16_zoltan)C++14
140 / 140
543 ms19232 KiB
#include <bits/stdc++.h> using namespace std; using ll = long long; using ull = unsigned long long; using ld = long double; using pii = pair<int, int>; using pll = pair<ll, ll>; #define rep(i, n) for (int (i) = 0; (i) < (n); ++(i)) #define all(x) (x).begin(), (x).end() #define f first #define s second #define FAST_IO ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0); #define left left123 #define right right123 const int MAXN = 2e5 + 5; const int mod = 1e9 + 7; int n; int a[MAXN]; pll t[MAXN * 4]; pll dpup[MAXN]; pll dpdown[MAXN]; ll pw[MAXN]; pll merge(const pll &a, const pll &b) { if (a.f == b.f) return {a.f, (a.s + b.s) % mod}; return max(a, b); } void build(int v, int tl, int tr) { t[v] = {0, 0}; if (tr - tl == 1) return; int tm = tl + (tr - tl) / 2; build(v * 2 + 1, tl, tm); build(v * 2 + 2, tm, tr); // for (int i = tl; i < tr; ++i) { // t[i] = {0, 0}; // } } void upd(int v, int tl, int tr, int p, pll x) { if (tr - tl == 1) { t[v] = merge(t[v], x); return; } int tm = tl + (tr - tl) / 2; if (p < tm) { upd(v * 2 + 1, tl, tm, p, x); } else { upd(v * 2 + 2, tm, tr, p, x); } t[v] = merge(t[v * 2 + 1], t[v * 2 + 2]); // t[p] = merge(t[p], x); } pll get(int v, int tl, int tr, int l, int r) { if (r <= tl || tr <= l) return {0, 0}; if (l <= tl && tr <= r) return t[v]; int tm = tl + (tr - tl) / 2; return merge(get(v * 2 + 1, tl, tm, l, r), get(v * 2 + 2, tm, tr, l, r)); // pll best = {0, 0}; // for (int i = l; i < r; ++i) { // best = merge(best, t[i]); // } // return best; } void compress() { vector<int> x; rep(i, n) { x.push_back(a[i]); } sort(all(x)); x.resize(unique(all(x)) - x.begin()); rep(i, n) { a[i] = lower_bound(all(x), a[i]) - x.begin(); } } int main() { pw[0] = 1; for (int i = 1; i < MAXN; ++i) { pw[i] = (pw[i - 1] * 2) % mod; } FAST_IO; cin >> n; rep(i, n) { cin >> a[i]; } compress(); for (int i = n - 1; i >= 0; --i) { dpup[i] = max(make_pair(0LL, 1LL), get(0, 0, n, a[i] + 1, n)); dpup[i].f++; upd(0, 0, n, a[i], dpup[i]); } build(0, 0, n); for (int i = n - 1; i >= 0; --i) { // cout << i << " : " << get(0, 0, n, 0, a[i]).f << endl; dpdown[i] = max(make_pair(0LL, 1LL), get(0, 0, n, 0, a[i])); dpdown[i].f++; upd(0, 0, n, a[i], dpdown[i]); } // rep(i, n) { // cout << "(" << dpup[i].f << ' ' << dpup[i].s << ") "; // } // cout << endl; // rep(i, n) { // cout << "(" << dpdown[i].f << ' ' << dpdown[i].s << ") "; // } // cout << endl; pll ans = {0, 1}; rep(i, n) { pll nw = {dpup[i].f, (dpup[i].s * pw[n - dpup[i].f - (i != 0)]) % mod}; ans = merge(ans, nw); if (i == 0) continue; nw = {dpdown[i].f, (dpdown[i].s * pw[n - dpdown[i].f - (i != 0)]) % mod}; ans = merge(ans, nw); } // if (ans.f == 1) { // ans = {1, n}; // }i build(0, 0, n + 1); for (int i = 1; i < n; ++i) { upd(0, 0, n + 1, a[i], dpdown[i]); } rep(i, n) { pll nw = get(0, 0, n + 1, 0, a[i]); nw.f += dpup[i].f; nw.s *= dpup[i].s; nw.s %= mod; if (i == 0) { nw.s *= pw[n - nw.f]; } else { nw.s *= pw[n - 1 - nw.f]; } nw.s %= mod; ans = merge(ans, nw); } // for (int i = n - 1; i >= 0; --i) { // // if (dpup[i].f == 1) continue; // for (int j = 1; j < n; ++j) { // if (i == j) continue; // if (a[j] >= a[i]) continue; // pll nw = {dpup[i].f + dpdown[j].f, (dpup[i].s * dpdown[j].s) % mod}; // // cout << nw.f << ' ' << nw.s << endl; // if (i == 0) { // nw.s *= pw[n - nw.f]; // } else { // nw.s *= pw[n - 1 - nw.f]; // } // nw.s %= mod; // ans = merge(ans, nw); // } // } if (ans.f == 1) { ans = {1, pw[n - 1] * n}; ans.s %= mod; } cout << ans.f << ' ' << ans.s << endl; }
#Verdict Execution timeMemoryGrader output
Fetching results...