#include #include #include #include #include #include #include #include #include #include #define REP(x,l,u) for(int x = (l);x<=(u);x++) using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair pii; const ll llmax=9223372036854775807; const ll llmin=-9223372036854775808; const int intmin=-2147483648; const int intmax=2147483647; const int mod=1e9+7; ll gcd(ll a,ll b){if(a==0 || b==0) return a+b;else return gcd(b,a%b);} template inline A fexp(A x,B p){A ans=1;for(;p;p>>=1,x=1LL*x*x%mod)if(p&1)ans=1LL*ans*x%mod;return ans;} template inline void read(T &x){ x=0;T f=1;char ch;do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9');do x=x*10+ch-'0',ch=getchar();while(ch<='9'&&ch>='0');x*=f; } vector primes; template bool isPrime(T x) { if (x <= 4 || x % 2 == 0 || x % 3 == 0) return x == 2 || x == 3; for (T i = 5; i * i <= x; i += 6) if (x % i == 0 || x % (i + 2) == 0) return 0; return 1; } template class ST{ struct Node{ int l,r; C sm,bjc,bjj; C min; C max; C oor; C andd; }; vector A; vector T; public: ST(vector& AA) { A.emplace_back(0);//to make it 1 indexed for(int i=0;i>1; build(i<<1,l,M);build(i<<1|1,M+1,r); pushup(i); } ll querySum(int i,int l,int r){ if(l<=T[i].l&&T[i].r<=r)return T[i].sm;// int M=T[i].l+T[i].r>>1;ll ans=0; pushdown(i); if(l<=M)ans+=querySum(i<<1,l,r);if(r>M)ans+=querySum(i<<1|1,l,r); return ans; } ll queryOr(int i,int l,int r){ if(l<=T[i].l&&T[i].r<=r)return T[i].oor;//((T[i].oor-T[i].andd)-(T[i].max-T[i].min)); int M=T[i].l+T[i].r>>1;ll ans=0; pushdown(i); if(l<=M)ans=queryOr(i<<1,l,r);if(r>M)ans|=queryOr(i<<1|1,l,r); return ans; } ll queryAnd(int i,int l,int r){ if(l<=T[i].l&&T[i].r<=r)return T[i].andd;//((T[i].oor-T[i].andd)-(T[i].max-T[i].min)); int M=T[i].l+T[i].r>>1;ll ans=0; pushdown(i); bool set=false; if(l<=M)ans=queryAnd(i<<1,l,r),set=true; if(r>M)ans=set?(ans&queryAnd(i<<1|1,l,r)):queryAnd(i<<1|1,l,r); return ans; } ll queryMax(int i,int l,int r){ if(l<=T[i].l&&T[i].r<=r)return T[i].max;//((T[i].oor-T[i].andd)-(T[i].max-T[i].min)); int M=T[i].l+T[i].r>>1;ll ans=llmin; pushdown(i); if(l<=M)ans=max(ans,queryMax(i<<1,l,r)); if(r>M)ans=max(ans,queryMax(i<<1|1,l,r)); return ans; } ll queryMin(int i,int l,int r){ if(l<=T[i].l&&T[i].r<=r)return T[i].min;//((T[i].oor-T[i].andd)-(T[i].max-T[i].min)); int M=T[i].l+T[i].r>>1;ll ans=llmax; pushdown(i); if(l<=M)ans=min(ans,queryMin(i<<1,l,r)); if(r>M)ans=min(ans,queryMin(i<<1|1,l,r)); return ans; } void add(int i,int l,int r,ll x){ if(l<=T[i].l&&T[i].r<=r){ add(i,x); return; } int M=T[i].l+T[i].r>>1; pushdown(i); if(l<=M)add(i<<1,l,r,x);if(r>M)add(i<<1|1,l,r,x); pushup(i); } void mul(int i,int l,int r,ll x){ if(l<=T[i].l&&T[i].r<=r){ mul(i,x); return; } int M=T[i].l+T[i].r>>1; pushdown(i); if(l<=M)mul(i<<1,l,r,x);if(r>M)mul(i<<1|1,l,r,x); pushup(i); } }; ll sum=0; int main() { //ios::sync_with_stdio(0), cin.tie(0); bool test= true; if(test) freopen("/Users/aj/code/HackerRank/input.txt", "r", stdin); ll n; cin>>n; vector val; int armax=0; REP(i,1,n){ int v; cin>>v; val.emplace_back(v); if(v>armax) armax=v; } ST st(val); vector B; REP(k,0,n-1){ REP(i,0,n-1-k){ ll l=i; ll r=i+k; l++,r++; ll mx=st.QueryMax(l,r); B.emplace_back(mx); } } int Blen=(int)B.size(); ll origsize=(ll)val.size(); REP(i,0,Blen-1){ bool ismax=false; int mxx=B[i]; REP(k,0,origsize){ if(i+k>=Blen) { ismax= true; break; } if(B[i]==armax){ sum+=(Blen-i)*armax; ismax=true; break; } if(B[i+k]>mxx) mxx=B[i+k]; sum+=mxx; sum%=mod; } if(!ismax) { ll left = Blen - (i + origsize+1); sum += left * armax % mod; sum %= mod; } } cout<