#include #define ff first #define ss second #define F(i,a,b) for ( int i = (int)(a); i < (int)(b); ++i ) #define PB push_back using namespace std; using ii = pair; using vi = vector; using ll = long long; const ii N_range = { 1, 1e9 }; const ii Q_range = { 1, 100 }; const int INF = 1e9+7; template struct SegmentTree { using value_type = NodeType; int n; vector st; SegmentTree(int size = 0) : n(size), st(vector(n+n)) { } // EDIT!!!! value_type NEUTRAL = 0; function apply = [] (value_type a, value_type b) { return a + b; }; // EDIT END void build(const vector & data) { // build the tree n = data.size(); st = vector(2 * n, NEUTRAL); for (int i = n; i < 2*n; ++i) st[i] = data[i-n]; for (int i = n - 1; i > 0; --i) st[i] = apply(st[i<<1], st[i<<1|1]); } void modify(int p, value_type value) { // set value at position p for (st[p += n] = value; p > 1; p >>= 1) st[p>>1] = apply(st[p], st[p^1]); } value_type query(int l, int r) { // query interval [l, r) // operation might not be comutative value_type left = NEUTRAL, right = NEUTRAL; for (l += n, r += n; l < r; l >>= 1, r >>= 1) { if (l&1) left = apply(left, st[l++]); if (r&1) right = apply(right, st[--r]); } return apply(left, right); } }; int main() { ios::sync_with_stdio(0); int n; assert(cin >> n && "Could not read N"); assert(N_range.ff <= n && n <= N_range.ss && "Invalid value of N"); SegmentTree maxst, gcdst; maxst.apply = [] (int a, int b) { return max(a, b); }; gcdst.apply = [] (int a, int b) { return __gcd(a, b); }; vector a(n); for (int & x : a) cin >> x; maxst.build(a); gcdst.build(a); int res = 0; F(i,0,n) { F(j,i,n) { // cout << maxst.query(i, j + 1) << " " << gcdst.query(i, j + 1) << endl; res = (res + (long) maxst.query(i, j + 1) * gcdst.query(i, j + 1)) % INF; } } cout << res << endl; return 0; }