/* -*- coding: utf-8 -*- * * 3613.cc: No.3613 Legendary Bread Maker - yukicoder */ #include #include #include #include using namespace std; /* constant */ const int MAX_N = 200000; /* typedef */ using ll = long long; struct Node { int v, f; Node *prv, *nxt; Node(): v(), f(), prv(), nxt() {} Node(int _v): v(_v), f(), prv(), nxt() {} void append(Node *p) { nxt = p, p->prv = this; } void remove() { f = 1; if (prv != nullptr) prv->nxt = nxt; if (nxt != nullptr) nxt->prv = prv; } }; using tp3 = tuple; /* global variables */ int as[MAX_N]; Node nodes[MAX_N]; /* subroutines */ /* main */ int main() { int n; scanf("%d", &n); for (int i = 0; i < n; i++) scanf("%d", as + i); priority_queue q; for (int i = 0; i < n; i++) { nodes[i].v = as[i]; if (i > 0) { auto *p0 = nodes + (i - 1), *p1 = nodes + i; p0->append(p1); q.push({-(ll)p0->v * p1->v, p0, p1}); } } auto *head = nodes, *tail = nodes + (n - 1); ll sum = 0; while (! q.empty()) { auto [g, p0, p1] = q.top(); q.pop(); if (p0->f || p1->f) continue; g = -g; sum += g; auto p = new Node(p0->v + p1->v); p0->remove(); p1->remove(); while (head != tail && head->f) head = head->nxt; while (tail != head && tail->f) tail = tail->prv; if (head == tail && head->f) break; if (head->v <= tail->v) { p->append(head); q.push({-(ll)p->v * head->v, p, head}); head = p; } else { tail->append(p); q.push({-(ll)tail->v * p->v, tail, p}); tail = p; } } printf("%lld\n", sum); return 0; }