Submission #681679

#TimeUsernameProblemLanguageResultExecution timeMemory
681679finn__Zoltan (COCI16_zoltan)C++17
28 / 140
497 ms29616 KiB
#include <bits/stdc++.h> using namespace std; #define MOD (1000000007 << 1) struct segtree { vector<pair<unsigned, uint64_t>> t; size_t l; segtree(size_t n) { l = 1 << (32 - __builtin_clz(n)); t = vector<pair<unsigned, uint64_t>>(2 * l, {0, 1}); } pair<unsigned, uint64_t> merge( pair<unsigned, uint64_t> const &a, pair<unsigned, uint64_t> const &b) { if (!a.first && !b.first) return {0, 1}; if (a.first == b.first) return make_pair(a.first, (a.second + b.second) % MOD); return max(a, b); } void update(size_t i, pair<unsigned, uint64_t> x) { i += l; if (t[i].first < x.first) t[i] = x; else if (t[i].first == x.first) t[i].second = (t[i].second + x.second) % MOD; else return; while (i > 1) { i >>= 1; t[i] = merge(t[2 * i], t[2 * i + 1]); } } pair<unsigned, uint64_t> range_max(size_t i, size_t j) { i += l, j += l; pair<unsigned, uint64_t> x = {0, 0}; while (i <= j) { if (i & 1) x = merge(x, t[i++]); if (!(j & 1)) x = merge(t[j--], x); i >>= 1; j >>= 1; } return x; } }; int main() { size_t n; cin >> n; vector<uint64_t> pow2(n + 1); pow2[0] = 1; for (size_t i = 1; i <= n; i++) pow2[i] = (pow2[i - 1] << 1) % MOD; vector<unsigned> y(n), z; for (unsigned &x : y) { cin >> x; z.push_back(x); } z.push_back(0); sort(z.begin(), z.end()); z.resize(unique(z.begin(), z.end()) - z.begin()); unordered_map<unsigned, unsigned> c; for (size_t i = 0; i < z.size(); i++) c[z[i]] = i; segtree t1(z.size() + 1), t2(z.size() + 1); for (size_t i = n - 1; i < n; i--) { pair<unsigned, uint64_t> x = t1.range_max(c[y[i]] + 1, z.size()); t1.update(c[y[i]], {x.first + 1, x.second}); x = t2.range_max(0, c[y[i]] - 1); t2.update(c[y[i]], {x.first + 1, x.second}); } pair<unsigned, uint64_t> ans = {0, 0}; for (size_t i = 0; i < n; i++) { auto a = t1.range_max(c[y[i]], z.size()); auto b = t2.range_max(0, c[y[i]] - 1); size_t r = a.first + b.first; if (r > ans.first) ans = {r, (a.second * b.second) % MOD}; else if (r == ans.first) ans.second = (ans.second + a.second * b.second) % MOD; } size_t p = 1; if (!(ans.second & 1)) { ans.second >>= 1; p = 0; } cout << ans.first << ' ' << (ans.second * pow2[n - ans.first - p]) % (MOD >> 1) << '\n'; }
#Verdict Execution timeMemoryGrader output
Fetching results...