#include using namespace std; typedef long long ll; typedef unsigned long long ull; typedef unsigned int ui; typedef long double ld; typedef pair ii; typedef pair iii; ll MOD = 1e9 + 7; const ld E = 1e-9; #define null NULL #define ms(x) memset(x, 0, sizeof(x)) #ifndef LOCAL #define endl "\n" #endif #ifndef LONG_LONG_MAX #define LONG_LONG_MAX LLONG_MAX #endif #define sync ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); #define _read(x) freopen(x, "r", stdin) #define _write(x) freopen(x, "w", stdout) #define files(x) _read(x ".in"); _write(x ".out") #define filesdatsol(x) _read(x ".DAT"); _write(x ".SOL") #define output _write("output.txt") #define input _read("input.txt") #define prev time_prev #ifndef M_PI #define M_PI acos(-1) #endif #define remove tipa_remove #define next tipa_next #define left tipa_left #define right tipa_right #define mod % MOD #define y1 hello_world unsigned char ccc; bool _minus = false; template inline T sqr(T t) { return (t * t); } inline void read(ll &n) { n = 0; _minus = false; while (true) { ccc = getchar(); if (ccc == ' ' || ccc == '\n') break; if (ccc == '-') { _minus = true; continue; } n = n * 10 + ccc - '0'; } if (_minus) n *= -1; } inline bool read(int &n) { n = 0; _minus = false; while (true) { ccc = getchar(); if (ccc == ' ' || ccc == '\n') { if (ccc == '\n') return true; break; } if (ccc == '-') { _minus = true; continue; } n = n * 10 + ccc - '0'; } if (_minus) n *= -1; return false; } char wwww[19]; int kkkk; inline void write(ll y) { long long x = y; kkkk = 0; if (x < 0) { putchar('-'); x *= -1; } if (!x) wwww[++kkkk] = '0'; else while (x) { ++kkkk; wwww[kkkk] = char(x % 10 + '0'); x /= 10; } for (int i = kkkk; i >= 1; --i) putchar(wwww[i]); } #ifdef LOCAL //#define __DEBUG #endif #ifdef __DEBUG #define dbg if(1) #else #define dbg if(0) #endif inline ll sum(ll n){ return (n * (n + 1)) / 2; } __int128 ans; const int MAX = 4e5 + 10; int ar[MAX]; ll tt[MAX]; ll ttt[MAX]; int n; ll culc(int a){ return tt[a] % MOD; } int t[MAX << 2]; void build(int v, int l, int r){ if(l == r){ t[v] = l; return; } int x = (l + r) >> 1; build(v << 1, l, x); build(v << 1 | 1, x + 1, r); t[v] = (ar[t[v << 1]] > ar[t[v << 1 | 1]] ? t[v << 1] : t[v << 1 | 1]); } int get_max(int v, int tl, int tr, int l, int r){ if(l <= tl && tr <= r){ return t[v]; } if(tr < l || r < tl){ return 0; } int x = (tl + tr) >> 1; int a = get_max(v << 1, tl, x, l, r); int b = get_max(v << 1 | 1, x + 1, tr, l, r); return (ar[a] > ar[b] ? a : b); } ll culc(int a, int b){ ll ans = sum(a); a--; int r = a + b; int l = a + b - 2 * min(a, b); l = max(l, 0); ans += ttt[r] - ttt[l]; int e = min(a, b); a -= e; b -= e; ans += culc(a) + culc(b); return ans; } int get_max(int l, int r){ return get_max(1, 1, n, l, r); } int get_max(int l1, int r1, int l2, int r2){ int a = get_max(l1, r1); int b = get_max(l2, r2); return (ar[a] > ar[b] ? a : b); } ll solve_1(int l, int r){ if(l > r) return 0; if(l == r){ ans += ar[l]; return 1; } int pos = get_max(l, r); ll has = culc(r - l + 1); has -= solve_1(l, pos - 1); has -= solve_1(pos + 1, r); has %= MOD; ans += has * ar[pos]; return culc(r - l + 1); } ll solve_2(int r, int l){ if(r == 0){ return solve_1(l, n); } if(l == n + 1){ return solve_1(1, r); } int pos = get_max(1, r, l, n); ll has = culc(r, n - l + 1); if(pos <= r){ has -= solve_2(pos - 1, l); has -= solve_1(pos + 1, r); }else{ has -= solve_2(r, pos + 1); has -= solve_1(l, pos - 1); } has %= MOD; ans += has * ar[pos]; return culc(r, n - l + 1); } namespace solve_long { vector get(vector v){ vector t; int n = (int) v.size(); for(int k = 0; k < n; k++){ for(int i = 0; i < n - k; i++){ int ans = 0; for(int j = i; j <= i + k; j++){ ans = max(ans, v[j]); } t.push_back(ans); } } return t; } int max_val = 0; int get_max(vector &v, int l, int r){ int pos = l; for(int i = l + 1; i <= r && v[pos] != max_val; i++){ if(v[i] > v[pos]){ pos = i; } } return pos; } ll sum(vector &v, int l, int r){ if(l > r) return 0; int pos = get_max(v, l, r); ll ans = (pos - l + 1) * 1LL * (r - pos + 1) * v[pos]; return ans + sum(v, l, pos - 1) + sum(v, pos + 1, r); } ll sum(vector v){ max_val = 0; for(int a : v){ max_val = max(max_val, a); } return sum(v, 0, (int) v.size() - 1); } __int128 solve(vector v){ return sum((get(v))) % MOD; } } ostream& operator<<(ostream &cout, __int128 a){ string s = ""; while(a){ s += char(a % 10 + '0'); a /= 10; } reverse(s.begin(), s.end()); cout << s; return cout; } __int128 solve_ok(vector v){ n = (int) v.size(); for(int i = 1; i <= n; i++){ ar[i] = v[i - 1]; } build(1, 1, n); ans = 0; __int128 g = n; g = (g * (g + 1)) / 2; g = (g * (g + 1)) / 2; int pos = get_max(1, n); g -= solve_2(pos - 1, pos + 1); ans += g * ar[pos]; return ans % MOD; } int main() { sync; srand((unsigned int) time(NULL)); cout.precision(10); cout << fixed; #ifdef LOCAL input; output; ll start = (ll) clock(); #else #endif for(int i = 1; i < MAX; i++){ tt[i] = sum(i) + tt[i - 1]; } for(int i = 1; i < MAX; i++){ ttt[i] = sum(i); if(i > 1){ ttt[i] += ttt[i - 2]; } } int n; cin >> n; vector v(n); for(int i = 0; i < n; i++){ cin >> v[i]; } cout << solve_ok(v) << endl; #ifdef LOCAL cout << "=====" << endl; cout << (clock() - start) * 1. / CLOCKS_PER_SEC << endl; cout << clock() << endl; cout << "=====" << endl; #endif // assert(false); }