#include using namespace std; typedef long long ll; const int MOD = 1e9+7, N = 2e5+5; ll fun[N],sf[N],sfeven[N],sfodd[N]; struct Triangle{ int l,r; bool operator<(const Triangle &t)const{ return l < t.l; } ll len()const{ int len = r-l+1; assert(len >= 0); return len; } ll f()const{ return sf[len()]; } ll combined_f(const Triangle &t)const{ ll a = len(), b = t.len(); ll ans = fun[a]; --a; if(a > b) swap(a,b); ll first = a+b; ll last = b-a; if(first%2) ans += sfodd[first]-(last<2 ? 0 : sfodd[last-2]); else ans += sfeven[first]-(last<2 ? 0 : sfeven[last-2]); ans += (last < 1 ? 0 : sf[last-1]); return ans; } }; set triangles; Triangle l_border,r_border; ll kill_pos(int pos){ if(l_border.l <= pos && pos <= l_border.r){ ll before = l_border.combined_f(r_border); Triangle new_tri = {pos+1,l_border.r}; l_border.r = pos-1; if(new_tri.len()) triangles.insert(new_tri); ll after = l_border.combined_f(r_border)+new_tri.f(); return ((before-after)%MOD+MOD)%MOD; }else if(r_border.l <= pos && pos <= r_border.r){ ll before = l_border.combined_f(r_border); Triangle new_tri = {r_border.l,pos-1}; r_border.l = pos+1; if(new_tri.len()) triangles.insert(new_tri); ll after = l_border.combined_f(r_border)+new_tri.f(); return ((before-after)%MOD+MOD)%MOD; }else{ Triangle searching = {pos,-1}; auto it = --triangles.upper_bound(searching); assert(it->l <= pos && pos <= it->r); Triangle tri1 = {it->l,pos-1}; Triangle tri2 = {pos+1,it->r}; ll diff = it->f() - tri1.f() - tri2.f(); triangles.erase(it); if(tri1.len()) triangles.insert(tri1); if(tri2.len()) triangles.insert(tri2); return (diff%MOD+MOD)%MOD; } } int main(){ for(ll i = 1; i < N; ++i) fun[i] = (i*(i+1)/2)%MOD; for(int i = 1; i < N; ++i){ sf[i] = sf[i-1] + fun[i]; sfodd[i] = sfodd[i-1]; sfeven[i] = sfeven[i-1]; if(i%2 == 1) sfodd[i] += fun[i]; else sfeven[i] += fun[i]; sf[i] %= MOD; sfodd[i] %= MOD; sfeven[i] %= MOD; } int n; cin >> n; vector > arr(n); for(int i = 0; i < n; ++i){ scanf("%d",&arr[i].first); arr[i].second = i; } sort(arr.rbegin(),arr.rend()); { int p = arr[0].second; l_border = {0,p-1}; r_border = {p+1,n-1}; } ll total_nr = (fun[n]*(fun[n]+1)/2)%MOD; //cout << arr[0].first << ' ' << total_nr << ' ' << l_border.combined_f(r_border) << '\n'; //cout << "total: " << total_nr << '\n'; //cout << "initial take: " << (total_nr - l_border.combined_f(r_border)) << '\n'; ll ans = (total_nr - l_border.combined_f(r_border))*arr[0].first; for(int i = 1; i < n; ++i){ ll tmp = kill_pos(arr[i].second); //cout << "Killed: " << tmp << '\n'; ans = (ans + tmp*arr[i].first)%MOD; } cout << ans%MOD << '\n'; }