#include using namespace std; const int N = 200020; const long long mod = 1e9 + 7; int n; int a[N]; int l[N]; int r[N]; int mark[N * 5]; int Rekt[N * 5]; int prefixMax[N]; int suffixMax[N]; long long val[N]; long long sqr[N]; long long sumVal[N]; long long revVal[N]; int clgt[N]; int greaterLeft[N]; namespace Buff{ vector < int > gen(vector < int > x){ vector < int > ans; for(int len = 0; len < x.size(); ++len){ for(int i = 0; i < x.size(); ++i){ if(i + len >= x.size()) break; int mx = 0; for(int p = i; p <= i + len; ++p){ mx = max(mx, x[p]); } ans.push_back(mx); } ans.push_back(-1); } return ans; } void ct(){ vector < int > vec; for(int i = 1; i <= n; ++i){ vec.push_back(a[i]); } vec = gen(vec); int f[15][4]; memset(f, 0, sizeof f); for(int i = 1; i < vec.size(); ++i){ if(vec[i] == -1 || vec[i - 1] == -1) continue; int mx = vec[i], cnt = 0, isRight = 0; for(int j = i + 1; j < vec.size(); ++j){ if(cnt == 1 && vec[j + 1] == -1) break; if(vec[j] == -1) { ++cnt; continue; } if(vec[j] > mx){ if(cnt == 1) isRight = 1; mx = vec[j]; } if(cnt == 1) ++f[mx][isRight]; } } for(int i = 1; i <= 6; ++i){ cout << "correct : " << i << " " << f[i][0] << " " << f[i][1] << endl; } } } long long calcLeft(int n1, int n2){ int x = min(n1, n2 - 1); long long ret = (1LL * x * n1 % mod) * n2 % mod - 1LL * val[x] * n1 % mod - 1LL * val[x] * n2 % mod + sqr[x] + 1LL * x * n2 - val[x] % mod; ret += mod * mod; ret %= mod; return ret; } long long calcRev(int l, int r){ long long ans = 0; for(int i = l; i <= r; ++i){ ans += i * (r - i + 1); } return ans; } long long myCalc(int l, int r){ return ((revVal[l] - revVal[r + 1] + mod) % mod - 1LL * (val[r] - val[l - 1] + mod) * (n - r) % mod + mod) % mod; } long long bruteForce(int n1, int n2){ long long ans = 0; for(int i = 1; i <= min(n1, n2 - 1); ++i){ ans += (n1 - i + 1) * (n2 - i); } return ans; } int firstGreater(int x){ return upper_bound(prefixMax + 1, prefixMax + n + 1, x) - prefixMax; } int main(){ if(fopen("1.inp", "r")){ freopen("1.inp", "r", stdin); } long long biggest = 0; scanf("%d", &n); for(int i = 1; i <= n; ++i){ scanf("%d", a + i); biggest = max(biggest, 1LL * a[i]); prefixMax[i] = max(prefixMax[i - 1], a[i]); } suffixMax[n] = a[n]; for(int i = n - 1; i >= 1; --i){ suffixMax[i] = max(suffixMax[i + 1], a[i]); } reverse(suffixMax + 1, suffixMax + n + 1); stack < int > f; for(int i = 1; i <= n; ++i){ while(!f.empty() && a[i] >= a[f.top()]){ r[f.top()] = i - 1; f.pop(); } if(f.empty()) l[i] = 1; else l[i] = f.top() + 1; f.push(i); } while(!f.empty()){ r[f.top()] = n; f.pop(); } for(int i = 1; i <= n; ++i){ val[i] = n - i + 1; val[i] += val[i - 1]; val[i] %= mod; } long long ans = (val[n] - val[1] + 1 + mod) * biggest % mod; for(int i = 2; i <= n; ++i){ long long now = val[i - 1] - val[i - 2] + mod; now %= mod; now = now * ((val[n] - val[i] + 1 + mod) % mod) % mod; ans += biggest * now % mod; ans %= mod; } for(int i = 1; i <= n; ++i){ val[i] = i; val[i] += val[i - 1]; val[i] %= mod; } for(int i = 1; i <= n; ++i){ sumVal[i] = sumVal[i - 1] + 1LL * i * i; sumVal[i] %= mod; } for(int i = n; i >= 1; --i){ revVal[i] = revVal[i + 1] + 1LL * i * (n - i + 1); revVal[i] %= mod; } for(int i = 1; i <= n; ++i){ int x = i - l[i] + 1; int y = r[i] - i + 1; int lim = min(x, y); int times = max(x, y) - lim + 1; ans += (1LL * a[i] * lim % mod) * (val[lim + times - 1] - val[lim - 1] + mod) % mod; ans %= mod; ans += sumVal[lim - 1] * a[i] % mod; ans %= mod; ans += 1LL * a[i] * myCalc(lim + times, x + y - 1) % mod; ans %= mod; if(x + y - 1 == n) ans -= 1LL * a[i] * n % mod; ans = (ans + mod) % mod; } for(int i = 1; i <= n; ++i){ val[i] = i; val[i] += val[i - 1]; val[i] %= mod; sqr[i] = 1LL * i * i % mod; sqr[i] += sqr[i - 1]; sqr[i] %= mod; } for(int i = n; i >= 1; --i){ if(r[i] != n) continue; int toleft = l[i]; int toright = l[i]; if(toright == 1) toright = n - 1; else toright = firstGreater(a[i]) - 1; toleft = max(toleft, 2); mark[a[i]] = i; if(toleft > i) continue; toleft = n - toleft + 1; // cout << a[i] << " : " << toleft << " " << toright << endl; ans += 1LL * a[i] * (calcLeft(toleft, toright) - calcLeft(n - i , toright) + mod ) % mod; ans %= mod; } for(int i = 1; i <= n; ++i){ if(l[i] != 1) continue; if(Rekt[a[i]]) continue; int toleft = mark[a[i]] + 1; if(!mark[a[i]]) { toleft = lower_bound(suffixMax + 1, suffixMax + n + 1, a[i]) - suffixMax; toleft = n + 1 - toleft + 1; } int toright = firstGreater(a[i]) - 1; if(toright == n) toright--; toleft = n - toleft + 1; ans += 1LL * (calcLeft(toleft, toright) - calcLeft(toleft, i - 1) + mod) * a[i] % mod; ans %= mod; Rekt[a[i]] = 1; } cout << ans; return 0; }