using System.Collections.Generic;
public static int mod = (int) 1e9 + 7;
public static int totalStrength(int[] power)
long[] forward = new long[n], backward = new long[n];
long[] prefix = new long[n + 1], suffix = new long[n + 1];
forward[0] = prefix[1] = power[0];
backward[n - 1] = suffix[n - 1] = power[n - 1];
for (int i = 1; i < n; ++i) {
forward[i] = power[i] + forward[i - 1];
prefix[i + 1] = prefix[i] + forward[i];
for (int i = n - 2; 0 <= i; --i) {
backward[i] = power[i] + backward[i + 1];
suffix[i] = suffix[i + 1] + backward[i];
var dq = new LinkedList<int>();
for (int i = 0; i < n; ++i) {
while (dq.Count > 0 && power[dq.Last.Value] >= power[i]) {
var prev = dq.Count == 0 ? -1 : dq.Last.Value;
res = (res + GetSum(power, forward, prefix, backward, suffix, prev, cur, i) * power[cur]) % mod;
var prev = dq.Count == 0 ? -1 : dq.Last.Value;
res = (res + GetSum(power, forward, prefix, backward, suffix, prev, cur, n) * power[cur]) % mod;
private static long GetSum(int[] nums, long[] forward, long[] prefix, long[] backward, long[] suffix, int prev, int cur, int next) {
long sum = ((cur - prev) * (long) nums[cur] % mod) * (next - cur) % mod;
long preSum = GetPresum(backward, suffix, prev + 1, cur - 1, next - cur);
long postSum = GetPostsum(forward, prefix, cur + 1, next - 1, cur - prev);
return (sum + preSum + postSum) % mod;
private static long GetPresum(long[] backward, long[] suffix, int from, int to, int m) {
int n = backward.Length, cnt = to - from + 1;
return (suffix[from] - suffix[to + 1] - cnt * (to + 1 == n ? 0 : backward[to + 1]) % mod) % mod * m % mod;
private static long GetPostsum(long[] forward, long[] prefix, int from, int to, int m) {
int n = forward.Length, cnt = to - from + 1;
return (prefix[to + 1] - prefix[from] - cnt * (0 == from ? 0 : forward[from - 1]) % mod) % mod * m % mod;
public static void Main()
var nums = new int[]{2,1,3};
var total = totalStrength(nums);
Console.WriteLine(total);