#include //----- BUILTIN---------// #define cnt64(n) (__builtin_popcountll(unsigned long long(n))) #define clz64(n) (64-__builtin_clzll(unsigned long long(n))) #define ctz64(n) (__builtin_ctzll(unsigned long long(n))) #define cnt32(n) (__builtin_popcount(int(n))) #define clz32(n) (32-__builtin_clz(int(n))) #define ctz32(n) (__builtin_ctz(int(n))) //----- TOOLS ----------// #define fori(i,n,k) for (int i = int(k); (i) < int(n); ++(i)) #define forr(i,n,k) for (int i = int(n)-1; (i) >= int(k); --(i)) #define in_range(i,l,r) (bool)(l <= i&&i <= r) #define all(v) v.begin(), v.end() #define PI 3.14159265358979323846 #define MOD 1000000007 #define MAXN 200001 using namespace std; typedef long long int lli; lli data[MAXN]; lli tree[MAXN<<2]; void build_tree(int node, int a, int b){ if(a > b) return; if(a==b){ tree[node] = data[a]; return; } build_tree(node<<1, a, (a+b)>>1); build_tree((node<<1)|1, 1+((a+b)>>1), b); tree[node] = max(tree[node<<1], tree[(node<<1)|1]); } lli query_tree(int node, int a, int b, int i, int j){ if(a > b || a > j || b < i) return 0; if(a >= i && b <= j) return tree[node]; lli q1 = query_tree(node<<1, a, (a+b)>>1, i, j); lli q2 = query_tree((node<<1)|1, 1+((a+b)>>1), b, i, j); return max(q1, q2); } int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); #ifndef __unix__ clock_t exc = clock(); //assert(freopen("input.txt", "r", stdin)); //assert(freopen("output.txt", "w", stdout)); #endif int n; cin >> n; fori(i, n, 0) cin >> data[i]; build_tree(1, 0, n-1); unordered_map cnt; lli idx; int x, y; lli tt = (1LL*n*n+n)>>1; tt = (tt*tt+tt)>>1; fori(k, n-1, 0) fori(i, n, 0){ if(i+k < n){ idx = i*n+i+k; cnt[idx]++; } else{ x = (i+k+1)%n; if(x p : cnt){ x = p.first/n; y = p.first%n; if(x <= y){ cnt[p.first] = y-x+1; tt -= y-x+1; } else tt--; } for(pair p : cnt){ x = p.first/n; y = p.first%n; if(x <= y) idx = query_tree(1, 0, n-1, x, y); else idx = max(query_tree(1, 0, n-1, x, n-1), query_tree(1, 0, n-1, 0, y)); s = (s+(p.second*idx)%MOD)%MOD; } s = (s+(tt*query_tree(1, 0, n-1, 0, n-1))%MOD)%MOD; cout << s << '\n'; #ifndef __unix__ cout << (double)(clock()-exc)/CLOCKS_PER_SEC*1000 << "ms.\n"; #endif return 0; }