#include using namespace std; #define ll long long typedef pair pii; #define f first #define s second #define mp make_pair const ll MOD = 1e9 + 7; const ll N = 1e6 + 5; const ll invTwo = 500000004; set st; ll n; ll arr[N], A[N], p[N]; ll prefix_max[N], suffix_max[N], psum_suff[N]; ll selalu_gitu[N]; vector v; int main() { A[0] = 0, A[1] = 1; p[0] = 0, p[1] = 1; for(ll i = 2; i < N; i++) { A[i] = (A[i - 2] + ((i*i)%MOD*i)%MOD)%MOD; p[i] = (p[i-1] + i)%MOD; } scanf("%lld",&n); for(int i = 1; i <= n; i++) { scanf("%lld",&arr[i]); v.push_back(mp(arr[i], i)); prefix_max[i] = max(prefix_max[i-1], arr[i]); } sort(v.begin(), v.end()); ll ans = 0; st.insert(0); st.insert(n+1); for(int i=v.size()-1; i >= 0; i--) { ll now = v[i].s; set::iterator it = st.lower_bound(now); ll r = *it; r-= 1; it--; ll l = *it; l+= 1; // untuk satu r : // r - l + r - (l + 1) + r - (l + 2) + r - (l + (now - l)) + 1 * (now - l + 1) // r * (now - l + 1) - l * (now - l + 1) - p[now-l] + (now - l + 1) // untuk banyak r : // (p[r] - p[now-1] + r-now+1) * (now - l + 1) - (r - now + 1) * (l * (now - l + 1) + p[now - l]) ll suku1 = (((p[r] - p[now-1]+MOD+r-now+1)%MOD) * (now - l + 1))%MOD; ll suku2 = ((r - now + 1) * (((l * (now - l + 1))%MOD) + p[now - l]))%MOD; suku1 = (suku1 - suku2 + MOD)%MOD; ans = (ans + suku1 * v[i].f)%MOD; st.insert(now); } for(ll i = n; i >= 1; i--) { suffix_max[i] = max(suffix_max[i+1], arr[i]); psum_suff[i] = (psum_suff[i+1] + suffix_max[i])%MOD; selalu_gitu[i] = (selalu_gitu[i+1] + (n-i+1)*suffix_max[i])%MOD; } // printf("ans sebelum : %lld\n",ans); ll last = n; for(ll L = 1; L <= n; L++) { while(suffix_max[last] < prefix_max[L]) last--; if (L == 1) continue; ll awal_max = last; ll pertama_min = max(L, n - L + 2); // pertama_min ke kanan = lebih kecil. Nilai awal N-L+2 // 1..N-L+2 ini sum n nya // L..N-L+2 // maks(A[r..n, 1..l]) * (min(l, n-r+2)-1) // printf("Untuk Loop L : %lld\n",L); // printf("awal_max : %lld\n",awal_max); // printf("pertama_min : %lld\n",pertama_min); ll sum_range = 0; if (awal_max >= pertama_min) { // L .. pertama_min - 1 ///// min(L) * (maksnya kanan) if (L <= pertama_min - 1) { ans = (ans + (L-1) * (psum_suff[L] - psum_suff[pertama_min]+MOD))%MOD; sum_range += (pertama_min - 1 - L + 1); } // printf("HOW\n"); // pertama_min .. awal_max // turun turunturun turun sama suffix_max suffix_max // (n-pertama_min+1)*suffix_max[pertama_min]+(n-pertama_min)*suffix_max[pertama_min+1] if (pertama_min <= awal_max) { // printf("HOWLX\n"); ans = (ans + (selalu_gitu[pertama_min] - selalu_gitu[awal_max+1] + MOD))%MOD; sum_range += (awal_max - pertama_min + 1); } // awal_max + 1.. n, selalu pake prefix_max[L], .. fixed prefix kiri, kanannya turun2 if (awal_max+1 <= n) { // printf("HOWLY\n"); sum_range += (n - (awal_max+1) + 1); ans = (ans + prefix_max[L] * p[n-(awal_max+1)+1])%MOD; } } else { // printf("HOW2\n"); // L .. awal_max if (L <= awal_max) { ans = (ans + (L-1) * (psum_suff[L] - psum_suff[awal_max+1] + MOD))%MOD; // printf("%lld...%lld\n",L,awal_max); sum_range += (awal_max - L + 1); } // awal_max + 1 .. pertama_min - 1 // fixed pake L, fixed pake prefix_kiri if (awal_max+1 <= pertama_min-1 && pertama_min-1 >= L) { awal_max += 1; awal_max = max(awal_max, L); sum_range += (pertama_min-1 - awal_max + 1); // printf("%lld...%lld\n",awal_max,pertama_min-1); ans = (ans + (((L-1) * prefix_max[L])%MOD) * (pertama_min-1-(awal_max)+1))%MOD; } // pertama_min .. n if (pertama_min <= n) { // printf("%lld...%lld\n",pertama_min,n); sum_range += (n - pertama_min + 1); ans = (ans + prefix_max[L] * p[n-pertama_min+1])%MOD; } } // printf("%lld %lld\n",L, ans); assert(sum_range == n-L+1); } // printf("magic : %lld\n",A[n-1]); ll magic = 0; for(int i = 1; i <= n; i++) magic = max(magic, arr[i]); ans %= MOD; if (ans < 0) ans += MOD; printf("%lld\n",(ans+A[n-1]*magic)%MOD); }