#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; #define MAX 200002 int n; map > mp; bool ava[MAX]; struct UF { vector belong; vector size; void resize(int n) { belong.assign(n + 1, -1); size.assign(n + 1, 1); } inline int root(int b) { if (belong[b] == -1) { return b; } belong[b] = root(belong[b]); return belong[b]; } void merge(int a, int b) { a = root(a); b = root(b); if (a == b)return; belong[a] = b; size[b] += size[a]; } }; UF uf; #define MOD 1000000007 bool use[MAX]; long long int dp[MAX]; inline long long int dfs(int b){ if(use[b]){ return dp[b]; } if(b==0){ return 0; } use[b]=true; long long int cnt=b; cnt *= (1LL + cnt); cnt /= 2LL; cnt%=MOD; cnt+=dfs(b-1); cnt%=MOD; dp[b]=cnt; return cnt; } inline long long int calc(int num) { return dfs(num); } long long int ppow(long long int i, long long int j) { long long int res = 1LL; while (j) { if ((j & 1LL)) { res *= i; if (res >= MOD) { res %= MOD; } } j >>= 1; i *= i; if (i >= MOD) { i %= MOD; } } return res; } bool use2[MAX]; long long int dp2[MAX]; inline long long int dfs2(int b){ if(b<=0){ return 0; } if(use2[b]){ return dp2[b]; } use2[b]=true; long long int cnt=b; cnt *= (1LL + cnt); cnt /= 2LL; if (cnt >= MOD)cnt %= MOD; cnt+=dfs2(b-2); dp2[b]=cnt; return cnt; } long long int mul(int a1,int a2){ if(a1<=0&&a2<=0)return 0; if(a1>a2){ swap(a1,a2); } long long int c=dfs2(a1+a2)+MOD-dfs2(a2-a1)+dfs(a2-a1); c%=MOD; return c; } long long int both(int a, int b) { long long int sum = 0; long long int cnt = a; cnt *= (1LL + cnt); cnt /= 2LL; if (cnt >= MOD)cnt %= MOD; sum += cnt; sum+=mul(a-1,b); sum %= MOD; return sum; } long long int previous_calc[MAX]; int main() { cin >> n; uf.resize(n); for (int i = 0; i < n; i++) { int a; scanf("%d", &a); mp[a].push_back(i); } long long int way = 0; long long int ans = 0; for (auto it = mp.begin(); it != mp.end(); it++) { auto nex = it; nex++; if (nex == mp.end())break; vector &vv = (*it).second; set er; if(ava[0])er.insert(uf.root(0) ); if(ava[n-1])er.insert(uf.root(n-1) ); for (int el : vv) { ava[el] = true; if (el&&ava[el - 1]) { er.insert(uf.root(el)); er.insert(uf.root(el-1)); uf.merge(el, el - 1); } if (ava[el + 1]) { er.insert(uf.root(el)); er.insert(uf.root(el+1)); uf.merge(el, el + 1); } } long long int inc=0; for(int k:er){ inc+=MOD-previous_calc[k]; previous_calc[k]=0; if(inc>=MOD)inc%=MOD; } set listen; if(ava[0])listen.insert(uf.root(0)); if(ava[n-1])listen.insert(uf.root(n-1)); for(int el:vv){ listen.insert(uf.root(el)); } bool ty=false; if(ava[0]&&ava[n-1]){ ty=true; } for (int j : listen) { if (uf.root(j) == j) { if(uf.root(0)==j||uf.root(n-1)==j){ if(ty){ continue; } } long long int c= calc(uf.size[uf.root(j) ]); previous_calc[uf.root(j)]=c; inc+=c; inc%=MOD; } else{ return 1; } } if (ty) { long long int c= both(uf.size[uf.root(0)], uf.size[uf.root(n - 1)]); previous_calc[uf.root(0)]=c; inc+=c; inc%=MOD; } long long int dif = inc; if (dif >= MOD)dif %= MOD; way += inc; way%=MOD; dif *= (*it).first; if (dif >= MOD)dif %= MOD; ans += dif; ans %= MOD; } long long int ALL = n; ALL *= (ALL + 1); ALL /= 2LL; ALL %= MOD; ALL *= (ALL + 1); ALL%=MOD; ALL *= ppow(2, MOD - 2); ALL %= MOD; ALL += MOD - (way%MOD); ALL *= (*mp.rbegin()).first; ALL %= MOD; ans += ALL; ans %= MOD; if(ans<0LL){ return 1; } printf("%lld\n", ans); return 0; }