#include using namespace std; #define FOR(a, b, c) for(int a = (b); a < (c); a++) #define SZ(a) (int)((a).size()) #define SIZE(a) (int)((a).size()) #define ALL(a) (a).begin(), (a).end() using ll = long long; #define LL long long #define PB push_back using pii = pair; #define S second #define F first const int N = 2e5 + 7; const int L = 18; const int MOD = 1e9 + 7; ll a[N], n; ll spar[2][N][L]; pii sparmax[N][L]; ll res = 0; void add(ll & a, ll b) { a += b; a %= MOD; } int query(int d, int l, int r) { int k = 31 - __builtin_clz(r - l + 1); return __gcd(spar[d][l][k], spar[d][r - (1 << k) + 1][k]); } // zwaraca pozycje max w przedziale [l, r] int querymax(int l, int r) { int k = 31 - __builtin_clz(r - l + 1); return max(sparmax[l][k], sparmax[r - (1 << k) + 1][k]).S; } void check(int l, int id, int r, int d) { ll cur = query(d, l, id); l = id; while(l <= r) { cur = __gcd(cur, spar[d][l][0]); int dl = 0; for(int x = L - 1; x >= 0; x--) { if(l + (1 << x) - 1 > r) { continue; } if(spar[d][l][x] % cur == 0) { dl += (1 << x); l += (1 << x); } } add(res, 1ll * spar[d][id][0] * dl * cur); } } void reku(int l, int r) { if(l > r) { return; } if(l == r) { add(res, 1ll * a[l] * a[l]); return; } int id = querymax(l, r); int dll = (id - l + 1), dlr = (r - id + 1); if(dll <= dlr) { // i = [l, id] FOR(i, l, id + 1) { check(i, id, r, 0); } } else { FOR(i, id, r + 1) { check(n - 1 - i, n - 1 - id, n - 1 - l, 1); } } reku(l, id - 1); reku(id + 1, r); } int main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin >> n; FOR(i, 0, n) { cin >> a[i]; } FOR(d, 0, 2) { FOR(i, 0, n) { spar[d][i][0] = a[i]; } for(int j = 1; (1 << j) <= n; j++) { for(int i = 0; i + (1 << j) - 1 < n; i++) { spar[d][i][j] = __gcd(spar[d][i][j - 1], spar[d][i + (1 << (j - 1))][j - 1]); } } reverse(a, a + n); } FOR(i, 0, n) { sparmax[i][0] = {a[i], i}; } for(int j = 1; (1 << j) <= n; j++) { for(int i = 0; i + (1 << j) - 1 < n; i++) { sparmax[i][j] = max(sparmax[i][j - 1], sparmax[i + (1 << (j - 1))][j - 1]); } } reku(0, n - 1); cout << res << "\n"; }