import java.io.*; import java.util.*; import java.text.*; import java.math.*; import java.util.regex.*; public class Solution { public static long getMaxTransformAllInOne(int[] input) { int size = input.length; // Number of times a number would be applied, if it is the highest amongst them all int numberOfTimesToApply = size + ((size * (size + 1)) / 2); // Initialize the full array int[] result = new int[(size * (size + 1)) / 2]; long value, valueK; int index; int round; long modulo = (long)Math.pow(10, 9) + 7; int diff; Map> sets = new TreeMap<>(Collections.reverseOrder()); Set set; for (int i=0; i < size; i++) { value = input[i]; set = sets.get(value); if (set == null) { set = new HashSet<>(); sets.put(value, set); } set.addAll(getIndeces(size, i, 0)); } Iterator iterator = sets.keySet().iterator(); Set previousIndexes = new HashSet<>(); Long number; long sum = 0L; while (iterator.hasNext()) { number = iterator.next(); set = sets.get(number); set.removeAll(previousIndexes); sum = (sum + set.size() * number) % modulo; previousIndexes.addAll(set); } return sum; } public static Set getIndeces(long length, final long index, int depth) { Set result = new HashSet<>(); long roundsFirstTime = ((length * (length + 1)) / 2); long roundsSecondTime = ((roundsFirstTime * (roundsFirstTime + 1)) / 2); // First round int round = 0; result.add(index); long newIndex = index; long pos = length; long windowSize = 0; long relativeIndexLeft, relativeIndexRight; result.add(index); long width = 0; while(pos < roundsFirstTime) { windowSize++; width = Math.min(index, windowSize); relativeIndexLeft = Math.max(index - width, 0); relativeIndexRight = Math.min(index, length + 1); for (long j = pos + relativeIndexLeft; j <= pos + relativeIndexRight && j < roundsFirstTime; j++) { result.add(j); } pos += length - windowSize; } if (depth == 0) { Set resultSet2 = new HashSet<>(); for(Long index2 : result) { resultSet2.addAll(getIndeces(roundsFirstTime, index2, 1)); } return resultSet2; } else { return result; } } public static List getMaxTransform(int[] input) { int size = input.length; // Initialize the full array List result = new ArrayList<>(); Integer zero = new Integer(0); for (long i = 0; i < (size * (size + 1)) / 2; i++) { result.add(zero); } int value, valueK; int index; int round; // Loop over the array and extend the size of the blocks (via K loop) for (int i=0; i < size; i++) { value = input[i]; int max = value; index = i; result.set(index, max); round = 0; for (int k=i+1; k < size; k++) { index += size - round++; valueK = input[k]; max = Math.max(max, valueK); result.set(index, max); } } return result; } public static long getMaxTransformSum(List input) { int size = input.size(); int value, valueK; int index; int round; long result = 0; long modulo = (long)Math.pow(10, 9) + 7; for (int i=0; i < size; i++) { value = input.get(i); int max = value; index = i; result = (result + max) % modulo; round = 0; for (int k=i+1; k < size; k++) { index += size - round++; valueK = input.get(k); max = Math.max(max, valueK); result += max; } } return result % modulo; } public static List getMaxTransformOld(List input) { List result = new ArrayList<>(); int j; int max; for (int k=0; k <= input.size() - 1; k++) { for (int i = 0; i <= input.size() - k - 1; i++) { j = i + k; max = 0; for (int l = i; l <= j; l++) { max = Math.max(max, input.get(l)); } result.add(max); } } return result; } static long solve(int[] A) { // Return the sum of S(S(A)) modulo 10^9+7. List maxTransform = getMaxTransform(A); int roundsFirstTime = ((A.length * (A.length + 1)) / 2); int roundsSecondTime = ((roundsFirstTime * (roundsFirstTime + 1)) / 2); int numberOfTimesToApply = A.length + ((A.length * (A.length + 1)) / 2); long result = getMaxTransformSum(maxTransform); return result; } static long solveNew(int[] A) { // Return the sum of S(S(A)) modulo 10^9+7. //int[] maxTransform = getMaxTransform(A); return getMaxTransformAllInOne(A); } public static void main(String[] args) { Scanner in = new Scanner(System.in); int n = in.nextInt(); int[] a = new int[n]; for(int a_i = 0; a_i < n; a_i++){ a[a_i] = in.nextInt(); } long result = solve(a); System.out.println(result); in.close(); } }