結果
問題 | No.919 You Are A Project Manager |
ユーザー | Haar |
提出日時 | 2020-04-08 19:48:29 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 153 ms / 3,000 ms |
コード長 | 8,515 bytes |
コンパイル時間 | 2,741 ms |
コンパイル使用メモリ | 224,336 KB |
実行使用メモリ | 5,376 KB |
最終ジャッジ日時 | 2024-07-19 05:21:37 |
合計ジャッジ時間 | 7,480 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge2 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 113 ms
5,248 KB |
testcase_01 | AC | 2 ms
5,248 KB |
testcase_02 | AC | 2 ms
5,376 KB |
testcase_03 | AC | 2 ms
5,376 KB |
testcase_04 | AC | 26 ms
5,376 KB |
testcase_05 | AC | 28 ms
5,376 KB |
testcase_06 | AC | 4 ms
5,376 KB |
testcase_07 | AC | 59 ms
5,376 KB |
testcase_08 | AC | 16 ms
5,376 KB |
testcase_09 | AC | 12 ms
5,376 KB |
testcase_10 | AC | 19 ms
5,376 KB |
testcase_11 | AC | 18 ms
5,376 KB |
testcase_12 | AC | 3 ms
5,376 KB |
testcase_13 | AC | 24 ms
5,376 KB |
testcase_14 | AC | 3 ms
5,376 KB |
testcase_15 | AC | 9 ms
5,376 KB |
testcase_16 | AC | 33 ms
5,376 KB |
testcase_17 | AC | 110 ms
5,376 KB |
testcase_18 | AC | 114 ms
5,376 KB |
testcase_19 | AC | 115 ms
5,376 KB |
testcase_20 | AC | 139 ms
5,376 KB |
testcase_21 | AC | 114 ms
5,376 KB |
testcase_22 | AC | 65 ms
5,376 KB |
testcase_23 | AC | 63 ms
5,376 KB |
testcase_24 | AC | 66 ms
5,376 KB |
testcase_25 | AC | 64 ms
5,376 KB |
testcase_26 | AC | 135 ms
5,376 KB |
testcase_27 | AC | 119 ms
5,376 KB |
testcase_28 | AC | 148 ms
5,376 KB |
testcase_29 | AC | 110 ms
5,376 KB |
testcase_30 | AC | 112 ms
5,376 KB |
testcase_31 | AC | 110 ms
5,376 KB |
testcase_32 | AC | 110 ms
5,376 KB |
testcase_33 | AC | 70 ms
5,376 KB |
testcase_34 | AC | 69 ms
5,376 KB |
testcase_35 | AC | 151 ms
5,376 KB |
testcase_36 | AC | 151 ms
5,376 KB |
testcase_37 | AC | 153 ms
5,376 KB |
testcase_38 | AC | 153 ms
5,376 KB |
testcase_39 | AC | 2 ms
5,376 KB |
testcase_40 | AC | 8 ms
5,376 KB |
testcase_41 | AC | 4 ms
5,376 KB |
testcase_42 | AC | 4 ms
5,376 KB |
testcase_43 | AC | 6 ms
5,376 KB |
testcase_44 | AC | 11 ms
5,376 KB |
testcase_45 | AC | 4 ms
5,376 KB |
testcase_46 | AC | 10 ms
5,376 KB |
testcase_47 | AC | 64 ms
5,376 KB |
testcase_48 | AC | 63 ms
5,376 KB |
testcase_49 | AC | 68 ms
5,376 KB |
testcase_50 | AC | 64 ms
5,376 KB |
testcase_51 | AC | 59 ms
5,376 KB |
testcase_52 | AC | 46 ms
5,376 KB |
testcase_53 | AC | 60 ms
5,376 KB |
testcase_54 | AC | 9 ms
5,376 KB |
testcase_55 | AC | 2 ms
5,376 KB |
testcase_56 | AC | 2 ms
5,376 KB |
testcase_57 | AC | 2 ms
5,376 KB |
ソースコード
#include <bits/stdc++.h> using i32 = int_fast32_t; using i64 = int_fast64_t; using u32 = uint_fast32_t; using u64 = uint_fast64_t; using f64 = double; using f80 = long double; #define FOR(v, a, b) for(i64 v = (a); v < (b); ++v) #define FORE(v, a, b) for(i64 v = (a); v <= (b); ++v) #define REP(v, n) FOR(v, 0, n) #define REPE(v, n) FORE(v, 0, n) #define REV(v, a, b) for(i64 v = (a); v >= (b); --v) #define ALL(x) (x).begin(), (x).end() #define RALL(x) (x).rbegin(), (x).rend() #define ITR(it, c) for(auto it = (c).begin(); it != (c).end(); ++it) #define RITR(it, c) for(auto it = (c).rbegin(); it != (c).rend(); ++it) #define EXIST(c,x) ((c).find(x) != (c).end()) #define fst first #define snd second #define UNIQ(v) (v).erase(unique(ALL(v)), (v).end()) #define bit(i) (1LL<<(i)) #ifdef DEBUG #include <Mylib/Debug/debug.cpp> #else #define dump(...) ((void)0) #endif using namespace std; template <typename I> void join(ostream &ost, I s, I t, string d=" "){for(auto i=s; i!=t; ++i){if(i!=s)ost<<d; ost<<*i;}ost<<endl;} template <typename T> istream& operator>>(istream &is, vector<T> &v){for(auto &a : v) is >> a; return is;} template <typename T> void pout(const T &value){std::cout << value << "\n";} template <typename T, typename ...Args> void pout(const T &value, const Args&... args){std::cout << value << " ";pout(args...);} template <typename T, typename U> bool chmin(T &a, const U &b){return (a>b ? a=b, true : false);} template <typename T, typename U> bool chmax(T &a, const U &b){return (a<b ? a=b, true : false);} template <typename T, size_t N, typename U> void fill_array(T (&a)[N], const U &v){fill((U*)a, (U*)(a+N), v);} template <typename T> auto make_vector(int n, int m, const T &value){return vector<vector<T>>(n, vector<T>(m, value));} struct Init{ Init(){ cin.tie(0); ios::sync_with_stdio(false); cout << fixed << setprecision(12); cerr << fixed << setprecision(12); } }init; struct SuccinctDict{ int N; static const int chunk_size = 256; static const int block_size = 64; std::vector<uint64_t> data; std::vector<std::vector<uint8_t>> blocks; std::vector<uint32_t> chunks; int chunk_num; static const int block_num = chunk_size / block_size; SuccinctDict(): N(0){} SuccinctDict(const std::vector<bool> &b): N(b.size()){ chunk_num = (N + chunk_size - 1) / chunk_size; data.assign(chunk_num * block_num + 1, 0); for(int i = 0; i < N; ++i){ if(b[i]){ int block_index = i / block_size; int index = i % block_size; data[block_index] |= (1LL << index); } } chunks.assign(chunk_num+1, 0); blocks.assign(chunk_num+1, std::vector<uint8_t>(block_num, 0)); for(int i = 0; i < chunk_num; ++i){ for(int j = 0; j < block_num-1; ++j){ blocks[i][j+1] = blocks[i][j] + __builtin_popcountll(data[i*block_num+j]); } chunks[i+1] = chunks[i] + blocks[i][block_num-1] + __builtin_popcountll(data[(i+1)*block_num-1]); } } /** * @return [0,index)のbの個数 */ inline int rank(int index, int b) const { if(b == 0){ return index - rank(index, 1); }else{ if(index > N) index = N; const int chunk_pos = index / chunk_size; const int block_pos = (index % chunk_size) / block_size; const uint64_t mask = data[chunk_pos * block_num + block_pos] & ((1LL << (index % block_size)) - 1); const int ret = chunks[chunk_pos] + blocks[chunk_pos][block_pos] + __builtin_popcountll(mask); return ret; } } /** * @return [s, e)のbの個数 */ inline int count(int s, int e, int b) const { return rank(e, b) - rank(s, b); } /** * @return b[index] */ inline int access(int index) const { return (data[index / block_size] >> (index % block_size)) & 1; } /** * @note n in [1, N] * @retval 0<= 先頭からn番目のbの位置 * @retval -1 n番目のbが存在しない */ inline int select(int n, int b) const { assert(n >= 1); if(rank(N, b) < n) return -1; int lb = -1, ub = N; while(abs(lb-ub) > 1){ int mid = (lb+ub) / 2; if(rank(mid, b) >= n){ ub = mid; }else{ lb = mid; } } return lb; } }; template <typename T, int B> class WaveletMatrix{ const int N; SuccinctDict sdict[B]; int zero_pos[B]; public: WaveletMatrix(std::vector<T> data): N(data.size()){ std::vector<bool> s(N); for(int k = 0; k < B; ++k){ std::vector<T> left, right; for(int i = 0; i < N; ++i){ s[i] = (data[i] >> (B-1-k)) & 1; if(s[i]){ right.push_back(data[i]); }else{ left.push_back(data[i]); } } sdict[k] = SuccinctDict(s); zero_pos[k] = left.size(); std::swap(data, left); data.insert(data.end(), right.begin(), right.end()); } } public: /** * @return data[index] */ inline T access(int index) const { T ret = 0; int p = index; for(int i = 0; i < B; ++i){ int t = sdict[i].access(p); ret |= ((T)t << (B-1-i)); p = sdict[i].rank(p, t) + t * zero_pos[i]; } return ret; } private: inline std::pair<int,int> rank_aux(int index, const T &val) const { int l = 0, r = index; for(int i = 0; i < B; ++i){ int t = (val >> (B-i-1)) & 1; l = sdict[i].rank(l, t) + t * zero_pos[i]; r = sdict[i].rank(r, t) + t * zero_pos[i]; } return std::make_pair(l, r); } public: /** * @return data[0,index)に含まれるvalの個数 */ inline int rank(int index, const T &val) const { int l, r; std::tie(l, r) = rank_aux(index, val); return r - l; } public: /* * @return data[s,e)に含まれるvalの個数 */ inline int count(int s, int e, const T &val) const { return rank(e, val) - rank(s, val); } public: /** * @retval 0<= count番目のvalの位置 * @retval -1 count番目のvalが存在しない */ int select(int count, const T &val) const { if(count <= 0) return -1; int l, r; std::tie(l, r) = rank_aux(N, val); if(r - l < count) return -1; int p = l + count - 1; for(int i = B-1; i >= 0; --i){ int t = (val >> (B-i-1)) & 1; p = sdict[i].select(p - t * zero_pos[i] + 1, t); } return p; } public: /** * @return data[l,r)でk(1-index)番目に小さい値 */ T quantile(int l, int r, int k) const { assert(0 <= l and l < r and r <= N); if(k == 0) return -1; T ret = 0; for(int i = 0; i < B; ++i){ const int count_1 = sdict[i].rank(r, 1) - sdict[i].rank(l, 1); const int count_0 = r - l - count_1; int t = 0; if(k > count_0){ t = 1; ret |= ((T)t << (B-i-1)); k -= count_0; } l = sdict[i].rank(l, t) + t * zero_pos[i]; r = sdict[i].rank(r, t) + t * zero_pos[i]; } return ret; } public: T maximum(int s, int e) const { return quantile(s, e, e-s); } public: T minimum(int s, int e) const { return quantile(s, e, 1); } public: int range_freq_lt(int, int, T) const; int range_freq(int, int, T, T) const; std::vector<std::pair<int,T>> range_freq_list(int, int, T, T) const; T next_value(int, int, T) const; T prev_value(int, int, T) const; std::vector<std::pair<int,T>> top_k(int, int, int) const; }; WaveletMatrix<uint32_t,32> make_wavelet_matrix_int(const std::vector<uint32_t> &data){ return WaveletMatrix<uint32_t, 32>(data); } const int H = 1000000000; int main(){ int N; cin >> N; vector<int> A(N); cin >> A; for(auto &x : A) x += H; auto wm = make_wavelet_matrix_int(vector<uint32_t>(ALL(A))); int64_t ans = LLONG_MIN; FORE(k,1,N){ vector<int64_t> left, right; left.push_back(0); right.push_back(0); for(int i = 0; i+k <= N; i += k){ left.push_back((int)wm.quantile(i, i+k, (k+1)/2) - H); } for(int i = N; i-k >= 0; i -= k){ right.push_back((int)wm.quantile(i-k, i, (k+1)/2) - H); } for(int i = 1; i < (int)left.size(); ++i) left[i] += left[i-1]; for(int i = 1; i < (int)right.size(); ++i) right[i] += right[i-1]; for(int i = 1; i < (int)right.size(); ++i) right[i] = max(right[i], right[i-1]); //dump(left, right); //reverse(ALL(right)); for(int i = 0; i < (int)left.size(); ++i){ chmax(ans, (left[i] + right.back()) * k); right.pop_back(); } } pout(ans); return 0; }