#include #define pii pair #define fi first #define se second #define mp make_pair #define pb push_back #define eb emplace_back #define pf push_front #define pb2 pop_back #define pf2 pop_front #define line printf("\n") #define pq priority_queue #define rep(k,i,j) for(int k = (int)i;k<(int)j;k++) #define repd(k,i,j) for(int k = (int)i;k>=(int)j;k--) #define ll long long #define ALL(a) a.begin(),a.end() #define vi vector using namespace std; double EPS = 1e-9; int INF = 1e9+7;; long long INFLL = 1e17; double pi = acos(-1); int dirx[8] = {-1,0,0,1,-1,-1,1,1}; int diry[8] = {0,1,-1,0,-1,1,-1,1}; clock_t first_attempt = clock(); inline void cek_time(){ clock_t cur = clock()- first_attempt; cerr<<"TIME : "<<(double) cur/CLOCKS_PER_SEC< #include using namespace __gnu_pbds; typedef tree, rb_tree_tag, tree_order_statistics_node_update> bbst; //end of template const int maxn = 2e5+5; const int invTwo = 500000004; ll f(ll a){ return a*(a+1)%INF*500000004%INF; } ll memoSingle[maxn]; ll oneSeg(ll a){ if(a<0)return 0; ll &ret = memoSingle[a]; if(ret!=-1)return ret; return ret = (oneSeg(a-1) + f(a))%INF; } ll memoOneSegTwo[maxn]; ll oneSegTwo(ll a){ if(a<0)return 0; ll &ret = memoOneSegTwo[a]; if(ret!=-1)return ret; return ret = (oneSegTwo(a-2) + f(a))%INF;; } ll twoSeg(ll a,ll b){ b--; b = max(b,0ll); if(a>b)swap(a,b); return (oneSegTwo(a+b) - oneSegTwo(b-a) + oneSeg(b-a))%INF; } int n; int arr[maxn], id[maxn]; int cmp(int a,int b) { return arr[a]>arr[b]; } set seg; void insert(pii a){ if(a.fi<=a.se)seg.insert(a); } void erase(pii a){ seg.erase(a); } ll len(pii a){ return max(a.se - a.fi + 1,0); } ll firstCut(int loc){ pii now = {0,n-1}; pii L = {0,loc-1}; pii R = {loc+1,n-1}; erase(now); insert(L); insert(R); // printf("%lld %lld\n",len(L),len(R)); return f(f(len(now))) - twoSeg(len(R), len(L)) - f(len(L)); } ll cut(int loc){ auto it = seg.upper_bound({loc,INF}); it--; pii L = {it->fi,loc-1}; pii R = {loc+1,it->se}; pii st = *seg.begin(), en = *seg.rbegin(); if(st.fi!=0)st= {0,-1}; if(en.se!=n-1)en= {0,-1}; ll ret = 0; if(*it==st){ ll onlyOne = f(len(st)) - f(len(L)) - f(len(R)); ll two = twoSeg(len(en), len(st)) - oneSeg(len(R)-1) - twoSeg(len(en), len(L)); // printf("cut st %lld %lld\n", onlyOne, two); // printf(" %lld %lld\n", twoSeg(len(en), len(st)), - f(len(R)) - twoSeg(len(en), len(L))); ret = onlyOne + two; } else if(*it==en) ret = twoSeg(len(en), len(st)) - oneSeg(len(L)) - twoSeg(len(R), len(st)); else ret = oneSeg(len(*it)) - oneSeg(len(L)) - oneSeg(len(R)); erase(*it); insert(L); insert(R); return ret%INF; } vi transform(vi x){ vi y; int n = x.size(); rep(k,0,n){ rep(i,0,n-k){ int num = 0; rep(j,i,i+k+1)num = max(num,x[j]); y.pb(num); } } return y; } ll bf(map ori){ vi arrbf = vi(arr,arr+n); // for(auto a : arrbf)printf("%d ",a);line; arrbf = transform(arrbf); // for(auto a : arrbf)printf("%d ",a);line; arrbf = transform(arrbf); int ret = 0; map cnt; // for(auto a : arrbf)printf("%d ",a);line; for(auto a : arrbf) ret += a, ret%= INF, cnt[a]++; printf("bf %d\n",ret); for(auto a : cnt){ printf("cnt %d : bf %d ori %d\n",a.fi,a.se, ori[a.fi]); } ll ans2 = 0; rep(k,0,n){ int maks = 0; rep(i,k,n+1){ maks = max(maks,arr[i]); ans2 += (ll)maks*(i-k+1)%INF*(i-k+1); ans2%=INF; } } // assert(ans2==ret); return ret; } int main(){ memset(memoSingle,-1,sizeof memoSingle); memset(memoOneSegTwo,-1,sizeof memoOneSegTwo); scanf("%d",&n); rep(k,0,n)scanf("%d",&arr[k]), id[k] = k; sort(id,id+n,cmp); seg.insert(mp(0,n-1)); ll ans = 0; map cnt; // rep(k,0,n)printf("%d ",arr[k]);line; rep(k,0,n){ int cur = id[k]; ll num = k?cut(cur):firstCut(cur); num %= INF; cnt[arr[cur]] += num; // printf("cur %d %d : %d\n",cur,arr[cur],num); ans += num*arr[cur]; ans%=INF; } if(ans<0)ans += INF; cout<