結果
問題 | No.919 You Are A Project Manager |
ユーザー |
|
提出日時 | 2019-11-08 07:44:44 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 827 ms / 3,000 ms |
コード長 | 3,657 bytes |
コンパイル時間 | 3,974 ms |
コンパイル使用メモリ | 247,200 KB |
最終ジャッジ日時 | 2025-01-08 02:26:42 |
ジャッジサーバーID (参考情報) |
judge3 / judge4 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 55 |
ソースコード
#include <bits/stdc++.h>#include <ext/pb_ds/assoc_container.hpp>#include <ext/pb_ds/tree_policy.hpp>#include <ext/pb_ds/tag_and_trait.hpp>#define REP(i, n) for (int i = 0; (i) < (int)(n); ++ (i))#define REP3(i, m, n) for (int i = (m); (i) < (int)(n); ++ (i))#define REP_R(i, n) for (int i = (int)(n) - 1; (i) >= 0; -- (i))#define REP3R(i, m, n) for (int i = (int)(n) - 1; (i) >= (int)(m); -- (i))#define ALL(x) std::begin(x), std::end(x)using namespace std;template <class T, class U> inline void chmax(T & a, U const & b) { a = max<T>(a, b); }template <class Key> using rb_tree_set = __gnu_pbds::tree<Key, __gnu_pbds::null_type, std::less<Key>, __gnu_pbds::rb_tree_tag, __gnu_pbds::tree_order_statistics_node_update>;int64_t solve(int n, const vector<int> & a) {// list queries for Mo's algorithmvector<pair<int, int> > queries;REP3 (k, 1, n + 1) {REP (i, n / k) {int l = k * i;int r = k * (i + 1);queries.emplace_back(l, r);}REP (i, n / k) {int l = n - k * (i + 1);int r = n - k * i;queries.emplace_back(l, r);}}// prepare the structure for Mo's algorithmrb_tree_set<pair<int, int> > used;int l = 0;int r = 0;auto add = [&](int i) {assert (i == l - 1 or i == r);used.insert(make_pair(a[i], i));if (i == l - 1) -- l;if (i == r) ++ r;};auto remove = [&](int i) {assert (i == l or i == r - 1);used.erase(make_pair(a[i], i));if (i == l) ++ l;if (i == r - 1) -- r;};auto get = [&]() {auto it = used.find_by_order((r - l - 1) / 2);assert (it != used.end());return it->first;};// run Mo's algorithmunordered_map<uint64_t, int> median;sort(ALL(queries));int sqrt_n = sqrt(n) + 3;for (int bl = 0, ql = 0; bl < n; ) {int br = min(n, bl + sqrt_n);int qr = ql;while (qr < queries.size() and queries[qr].first < br) {++ qr;}sort(queries.begin() + ql, queries.begin() + qr, [&](pair<int, int> a, pair<int, int> b) {return a.second < b.second;});REP3 (i, ql, qr) {int nl, nr; tie(nl, nr) = queries[i];while (r < nr) add(r);while (nl < l) add(l - 1);while (nr < r) remove(r - 1);while (l < nl) remove(l);median[((uint64_t)nl << 32) | nr] = get();}bl = br;ql = qr;}// compute the answerint64_t answer = INT64_MIN;vector<int64_t> left, right;REP3 (k, 1, n + 1) {int cnt = n / k;// list left groupsint64_t sum_left = 0;left.assign(cnt + 1, 0);REP (i, cnt) {int l = k * i;int r = k * (i + 1);sum_left += median.at(((uint64_t)l << 32) | r);left[i + 1] = max(left[i], sum_left);}// list right groupsint64_t sum_right = 0;right.assign(cnt + 1, 0);REP (i, cnt) {int l = n - k * (i + 1);int r = n - k * i;sum_right += median.at(((uint64_t)l << 32) | r);right[i + 1] = max(right[i], sum_right);}// convolutionREP (i, left.size()) {int j = right.size() - i - 1;chmax(answer, k * (left[i] + right[j]));}}return answer;}int main() {int n; cin >> n;vector<int> a(n);REP (i, n) {cin >> a[i];}cout << solve(n, a) << endl;return 0;}