#include using namespace std; // A utility function to get minimum of two numbers int maxVal(int x, int y) { return (x > y)? x: y; } // A utility function to get the middle index from corner indexes. int getMid(int s, int e) { return s + (e -s)/2; } /* A recursive function to get the minimum value in a given range of array indexes. The following are parameters for this function. st --> Pointer to segment tree index --> Index of current node in the segment tree. Initially 0 is passed as root is always at index 0 ss & se --> Starting and ending indexes of the segment represented by current node, i.e., st[index] qs & qe --> Starting and ending indexes of query range */ int RMQUtil(vector &st, int ss, int se, int qs, int qe, int index) { // If segment of this node is a part of given range, then return // the min of the segment if (qs <= ss && qe >= se) return st[index]; // If segment of this node is outside the given range if (se < qs || ss > qe) return INT_MIN; // If a part of this segment overlaps with the given range int mid = getMid(ss, se); return maxVal(RMQUtil(st, ss, mid, qs, qe, 2*index+1), RMQUtil(st, mid+1, se, qs, qe, 2*index+2)); } int RMQ(vector &st, int n, int qs, int qe) { // // Check for erroneous input values // if (qs < 0 || qe > n-1 || qs > qe) // { // printf("Invalid Input"); // return -1; // } return RMQUtil(st, 0, n-1, qs, qe, 0); } int constructSTUtil(vector &arr, int ss, int se, vector &st, int si) { if (ss == se) { st[si] = arr[ss]; return arr[ss]; } int mid = getMid(ss, se); st[si] = maxVal(constructSTUtil(arr, ss, mid, st, si*2+1), constructSTUtil(arr, mid+1, se, st, si*2+2)); return st[si]; } vector constructST(vector &arr, int n) { // Allocate memory for segment tree //Height of segment tree int x = (int)(ceil(log2(n))); // Maximum size of segment tree int max_size = 2*(int)pow(2, x) - 1; vector st(max_size); // Fill the allocated memory st constructSTUtil(arr, 0, n-1, st, 0); // Return the constructed segment tree return st; } int solve(vector &A) { // Return the sum of S(S(A)) modulo 10^9+7. vector st = constructST(A,A.size()); vector B; long long ans=0; for(int k=0;k< A.size();++k){ for(int i=0;i< A.size()-k;++i){ B.push_back(RMQ(st,A.size(),i, i+k)); } } vector st2 = constructST(B,B.size()); for(int k=0;k< B.size();++k){ for(int i=0;i< B.size()-k;++i){ ans= (ans%1000000007+RMQ(st2,B.size(),i, i+k)%1000000007)%1000000007; } } return ans; } int main() { int n; cin >> n; vector a(n); for(int a_i = 0; a_i < n; a_i++){ cin >> a[a_i]; } int result = solve(a); cout << result << endl; return 0; }