/** * author: tourist * created: 14.12.2017 19:47:19 **/ #include using namespace std; string to_string(string s) { return '"' + s + '"'; } string to_string(const char* s) { return to_string((string) s); } string to_string(bool b) { return (b ? "true" : "false"); } template string to_string(pair p) { return "(" + to_string(p.first) + ", " + to_string(p.second) + ")"; } template string to_string(A v) { bool first = true; string res = "{"; for (const auto &x : v) { if (!first) { res += ", "; } first = false; res += to_string(x); } res += "}"; return res; } void debug_out() { cerr << endl; } template void debug_out(Head H, Tail... T) { cerr << " " << to_string(H); debug_out(T...); } #ifdef LOCAL #define debug(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__) #else #define debug(...) 42 #endif const int md = (int) 1e9 + 7; inline void add(int &a, int b) { a += b; if (a >= md) a -= md; } inline void sub(int &a, int b) { a -= b; if (a < 0) a += md; } inline int mul(int a, int b) { return (int) ((long long) a * b % md); } inline int power(int a, long long b) { int res = 1; while (b > 0) { if (b & 1) { res = mul(res, a); } a = mul(a, a); b >>= 1; } return res; } inline int inv(int a) { a %= md; if (a < 0) a += md; int b = md, u = 0, v = 1; while (a) { int t = b / a; b -= t * a; swap(a, b); u -= t * v; swap(u, v); } assert(b == 1); if (u < 0) u += md; return u; } int main() { int n; scanf("%d", &n); vector< pair > a(n); for (int i = 0; i < n; i++) { scanf("%d", &a[i].first); a[i].second = i; } sort(a.begin(), a.end()); set s; for (int i = -1; i <= n; i++) { s.insert(i); } vector mem(n + 1); mem[0] = 0; for (int i = 1; i <= n; i++) { mem[i] = mem[i - 1]; add(mem[i], mul(mul(i, i + 1), inv(2))); } int cc = 0; int ans = 0; int cc_border = 0; for (int it = 0; it < n - 1; it++) { int i = a[it].second; s.erase(i); int y = *s.lower_bound(i) - i - 1; int x = i - *(--s.lower_bound(i)) - 1; int cnt = mem[x + y + 1]; sub(cnt, mem[x]); sub(cnt, mem[y]); /* for (int k = 1; k <= x + y + 1; k++) { int lft = max(x - k + 1, 0); int rgt = max(y - k + 1, 0); int final = x + y + 1 - k + 1; int cur = (int) (((long long) final * (final + 1) / 2 - (long long) lft * (lft + 1) / 2 - (long long) rgt * (rgt + 1) / 2) % md); debug(x, y, k, lft, rgt, final, cur); add(cnt, cur); }*/ debug(cnt); add(cc, cnt); add(ans, mul(cnt, a[it].first)); { x = *s.lower_bound(0); y = n - 1 - *(--s.lower_bound(n)); debug(x, y); int cnt_border = 0; if (min(y, x - 1) >= 1) { int A = x - 1; int B = y; int C = min(A, B); A = A - C + 1; B = B - C + 1; add(cnt_border, mul(mul(A, B), C)); add(cnt_border, mul(A + B, mul(mul(C, C - 1), inv(2)))); add(cnt_border, mul(mul(C - 1, C), mul(2 * C - 1, inv(6)))); debug(A, B, C, cnt_border); } /* int old_cnt_border = 0; for (int k = 1; k <= min(y, x - 1); k++) { int cur = mul(x - 1 - k + 1, y - k + 1); add(old_cnt_border, cur); } debug(old_cnt_border);*/ int new_border = cnt_border; sub(new_border, cc_border); add(ans, mul(new_border, a[it].first)); cc_border = cnt_border; } } int subs = (int) ((long long) n * (n + 1) / 2 % md); int all = mul(mul(subs, subs + 1), inv(2)); int maximum = all; sub(maximum, cc); sub(maximum, cc_border); add(ans, mul(maximum, a[n - 1].first)); cout << ans << endl; return 0; }