#include 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 #else #define dump(...) ((void)0) #endif using namespace std; template void join(ostream &ost, I s, I t, string d=" "){for(auto i=s; i!=t; ++i){if(i!=s)ost< istream& operator>>(istream &is, vector &v){for(auto &a : v) is >> a; return is;} template void pout(const T &value){std::cout << value << "\n";} template void pout(const T &value, const Args&... args){std::cout << value << " ";pout(args...);} template bool chmin(T &a, const U &b){return (a>b ? a=b, true : false);} template bool chmax(T &a, const U &b){return (a void fill_array(T (&a)[N], const U &v){fill((U*)a, (U*)(a+N), v);} template auto make_vector(int n, int m, const T &value){return vector>(n, vector(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 data; std::vector> blocks; std::vector chunks; int chunk_num; static const int block_num = chunk_size / block_size; SuccinctDict(): N(0){} SuccinctDict(const std::vector &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(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 class WaveletMatrix{ const int N; SuccinctDict sdict[B]; int zero_pos[B]; public: WaveletMatrix(std::vector data): N(data.size()){ std::vector s(N); for(int k = 0; k < B; ++k){ std::vector 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 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> range_freq_list(int, int, T, T) const; T next_value(int, int, T) const; T prev_value(int, int, T) const; std::vector> top_k(int, int, int) const; }; WaveletMatrix make_wavelet_matrix_int(const std::vector &data){ return WaveletMatrix(data); } const int H = 1000000000; int main(){ int N; cin >> N; vector A(N); cin >> A; for(auto &x : A) x += H; auto wm = make_wavelet_matrix_int(vector(ALL(A))); int64_t ans = LLONG_MIN; FORE(k,1,N){ vector 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; }