Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include<stdio.h>
- #include<iostream>
- #include<vector>
- #include<algorithm>
- #include<string>
- #include<string.h>
- using namespace std;
- typedef long long LL;
- typedef vector<int> VI;
- #define REP(i,n) for(int i=0, i##_len=(n); i<i##_len; ++i)
- #define EACH(i,c) for(__typeof((c).begin()) i=(c).begin(),i##_end=(c).end();i!=i##_end;++i)
- #define eprintf(...) fprintf(stderr, __VA_ARGS__)
- template<class T> inline void amin(T &x, const T &y) { if (y<x) x=y; }
- template<class T> inline void amax(T &x, const T &y) { if (x<y) x=y; }
- template<class Iter> void rprintf(const char *fmt, Iter begin, Iter end) {
- for (bool sp=0; begin!=end; ++begin) { if (sp) putchar(' '); else sp = true; printf(fmt, *begin); }
- putchar('\n');
- }
- template<class T> struct IRXQ {
- int n, g; T *d;
- IRXQ() : n(0), g(0), d(NULL) {}
- template<class Iter> IRXQ(Iter begin, Iter end) : n(0), g(0), d(0) { build(begin, end); }
- IRXQ(const IRXQ &y) : n(y.n), g(0), d(NULL) { if (y.n) build(y.d[0], y.d[0] + n); }
- IRXQ(IRXQ &&y) : n(0), g(0), d(NULL) { swap(*this, y); }
- ~IRXQ() { if (n) { n = 0; delete d; d = NULL; } }
- friend void swap(IRXQ &x, IRXQ &y) { swap(x.n, y.n); swap(x.d, y.d); }
- IRXQ& operator=(IRXQ y) { swap(*this, y); return *this; }
- template<class Iter> void build(Iter begin, Iter end) { // random access iterator
- n = end - begin;
- if (n == 0) return;
- g = __lg(n);
- d = new T[n*(g+1)];
- REP (i, n) { d[i] = *begin; ++begin; }
- for (int t=0, b=0; t<g; t++, b+=n) for (int i=0, j=1<<t; j<=n-(1<<t); i++, j++)
- d[b+n+i] = (d[b+i] < d[b+j]? d[b+j]: d[b+i]);
- }
- const T at(int i) const { return d[i]; }
- const T max_v(int l, int r) const {
- int h = __lg(r - l), b = n * h;
- r -= 1<<h;
- return d[b+l] < d[b+r]? d[b+r]: d[b+l];
- }
- int max_i(int l, int r) const {
- return first_more_equal(l, max_v(l, r));
- }
- // for i in [l .. n-1]:
- // if at(i) > v: return i;
- // return n;
- int first_more_than(int l, const T v) const {
- for (int t=g+1; t--; )
- if (l + (1<<t) <= n && !(v < d[n*t+l]))
- l += 1 << t;
- return l;
- }
- // for i in [l .. n-1]:
- // if v <= at(i): return i;
- // return n;
- int first_more_equal(int l, const T v) const {
- for (int t=g+1; t--; )
- if (l + (1<<t) <= n && d[n*t+l] < v)
- l += 1 << t;
- return l;
- }
- // for i in [r-1 .. 0]:
- // if v < at(i): return i;
- // return n;
- int last_more_than(int r, const T v) const {
- for (int t=g+1; t--; )
- if (0 <= r - (1<<t) && !(v < d[n*t+r-(1<<t)]))
- r -= 1 << t;
- return r? r-1: n;
- }
- // for i in [r-1 .. 0]:
- // if v <= at(i): return i;
- // return n;
- int last_more_equal(int r, const T v) const {
- for (int t=g+1; t--; )
- if (0 <= r - (1<<t) && d[n*t+r-(1<<t)] < v)
- r -= 1 << t;
- return r? r-1: n;
- }
- };
- typedef unsigned long long ULL;
- ULL gcd(ULL x, ULL y) {
- while (1) {
- if (x) y %= x; else return y;
- if (y) x %= y; else return x;
- }
- }
- int N;
- int A[50011];
- LL sums[50011];
- ULL G[17][50011];
- ULL gcdx(int L, int R) {
- int t = __lg(R - L);
- return gcd(G[t][L], G[t][R - (1<<t)]);
- }
- void MAIN() {
- scanf("%d", &N);
- REP (i, N) scanf("%d", A+i);
- REP (i, N) {
- G[0][i] = abs(A[i]);
- sums[i+1] = sums[i] + A[i];
- }
- IRXQ<int> M(A, A+N);
- IRXQ<LL> S(sums, sums+N+1);
- REP (t, 16) {
- REP (i, N) {
- int s = i + (1<<t);
- if (s < N) {
- G[t+1][i] = gcd(G[t][i], G[t][s]);
- }
- }
- }
- LL ans = 0;
- REP (i, N) if (A[i] > 0) {
- int pos = i;
- while (1) {
- int lo = pos+1, hi = N+1;
- ULL g = gcdx(i, lo);
- while (hi - lo > 1) {
- int mid = (lo + hi) / 2;
- if (gcdx(i, mid) == g) lo = mid;
- else hi = mid;
- }
- // [i, lo)
- // [pos, lo)
- int idx = S.max_i(pos+1, lo+1);
- int ma = M.max_v(i, idx);
- LL s = sums[idx] - sums[i];
- amax(ans, (LL)g * (s - ma));
- if (lo == N) break;
- pos = lo;
- }
- }
- printf("%lld\n", ans);
- }
- int main() {
- int TC = 1;
- // scanf("%d", &TC);
- REP (tc, TC) MAIN();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement