#include using namespace std; #define MAXN 200010 #define MAXM 1000000 #define INF 0x3f3f3f3f #define mo 1000000007 typedef long long LL; int n, ans, segcnt; int a[MAXN], b[MAXN]; int f[MAXN], l[MAXN], r[MAXN]; LL tree[4][MAXM + 10]; bool vis[MAXN]; void Init() { srand(time(0)); ans = segcnt = 0; scanf("%d", &n); for(int i = 1; i <= n; ++i) scanf("%d", a + i); } int Find(int u) { return f[u] ? f[u] = Find(f[u]) : u; } inline int Sum1(int i, int l, int r) { return (1LL * (i + r) * (r - i + 1) / 2 * (i - l + 1) - 1LL * (i + l - 2) * (i - l + 1) / 2 * (r - i + 1)) % mo; } void Solve1() { memset(vis, 0, sizeof(vis)); int i, j, fv, ret; for(i = 1; i <= n; ++i) b[i] = i; sort(b + 1, b + 1 + n, [](const int &x, const int &y){return a[x] < a[y]; }); for(i = 1; i <= n; ++i){ j = b[i]; vis[j] = true; l[j] = r[j] = j; f[j] = 0; if(vis[j - 1]){ fv = Find(j - 1); f[fv] = j; l[j] = l[fv]; } if(vis[j + 1]){ fv = Find(j + 1); f[fv] = j; r[j] = r[fv]; } ret = Sum1(j, l[j], r[j]); ans = (ans + 1LL * a[j] * ret) % mo; segcnt += ret; if(segcnt >= mo) segcnt -= mo; } } void Update(int k, int i, int v) { for(; i <= MAXM; tree[k][i] += v, i += i & -i); } int Prefix(int k, int i) { LL res = 0; for(; i; res += tree[k][i], i -= i & -i); (res >= mo) && (res %= mo); return res; } void Solve2() { memset(l, 0, sizeof(l)); memset(r, 0, sizeof(r)); int i, res = 0; for(i = n; i; --i){ l[i] = max(l[i + 1], a[i]); Update(0, l[i], 1); Update(1, MAXM - l[i] + 1, l[i]); } for(i = 2, r[0] = a[1]; i <= n; ++i){ r[i - 1] = max(r[i - 2], a[i]); Update(2, r[i - 1], 1); Update(3, MAXM - r[i - 1] + 1, r[i - 1]); } for(i = 1; i <= n; ++i){ res = (res + 1LL * l[i] * Prefix(2, l[i])) % mo; res += Prefix(3, MAXM - l[i]); if(res >= mo) res -= mo; } for(i = 1; i < n; ++i){ ans += res; if(ans >= mo) ans -= mo; segcnt = (segcnt + 1LL * (n - i + 1) * (n - i)) % mo; res = (res + mo - 1LL * l[n - i + 1] * Prefix(2, l[n - i + 1]) % mo) % mo; res -= Prefix(3, MAXM - l[n - i + 1]); if(res < 0) res += mo; Update(0, l[n - i + 1], -1); Update(1, MAXM - l[n - i + 1] + 1, -l[n - i + 1]); res = (res + mo - 1LL * r[i] * Prefix(0, r[i]) % mo) % mo; res -= Prefix(1, MAXM - r[i]); if(res < 0) res += mo; Update(2, r[i], -1); Update(3, MAXM - r[i] + 1, -r[i]); } } void Solve3() { LL N = 1LL * (n + 1) * n / 2; if(N & 1) segcnt = ((N + 1) / 2 % mo * (N % mo) + mo - segcnt) % mo; else segcnt = (N / 2 % mo * ((N + 1) % mo) + mo - segcnt) % mo; ans = (ans + 1LL * segcnt * l[1]) % mo; } int main() { #ifdef MYCP freopen("data.in", "r", stdin); #endif // MYCP Init(); Solve1(); Solve2(); Solve3(); printf("%d\n", ans); return 0; }