#include using namespace std; #define FOR(i, a, b) for (int i = (int)(a); i < (int)(b); ++i) #define REP(i, n) FOR(i, 0, n) #define TRACE(x) cerr << #x << " = " << x << endl #define X first #define Y second typedef long long llint; const int MAXN = 2e5 + 10; int gcd(int a, int b) { if(!a) return b; return gcd(b % a, a); } int n; int niz[MAXN]; int rj; const int OFF = 1 << 20; const int off = 1 << 19; const int MOD = 1e9 + 7; typedef pair par; inline int add(int a, int b) { int ret = a + b; if(ret >= MOD) ret -= MOD; return ret; } inline int mul(int a, int b) { llint ret = (llint) a * b; if(ret >= MOD) ret %= MOD; return ret; } llint tur[OFF]; llint prop[OFF]; void refresh(int cvor, int a, int b) { if(prop[cvor] == 0) return; tur[cvor] = (llint) (b - a + 1) * prop[cvor]; if(a < b) { prop[2 * cvor] = prop[cvor]; prop[2 * cvor + 1] = prop[cvor]; } prop[cvor] = 0; } void update(int cvor, int a, int b, int lo, int hi, int v) { if(a > hi || b < lo) return; refresh(cvor, a, b); if(a >= lo && b <= hi) { prop[cvor] = v; refresh(cvor, a, b); return; } update(2 * cvor, a, (a + b) / 2, lo, hi, v); update(2 * cvor + 1, (a + b) / 2 + 1, b, lo, hi, v); tur[cvor] = tur[2 * cvor] + tur[2 * cvor + 1]; } llint query(int cvor, int a, int b, int lo, int hi) { if(a > hi || b < lo) return 0; refresh(cvor, a, b); if(a >= lo && b <= hi) return tur[cvor]; llint ret = query(2 * cvor, a, (a + b) / 2, lo, hi); ret += query(2 * cvor + 1, (a + b) / 2 + 1, b, lo, hi); return ret; } int main(void) { scanf("%d", &n); FOR(i, 1, n + 1) scanf("%d", &niz[i]); stack s; // za maksimum vector v; // za gcd //parovi: (pos, value) FOR(br, 1, n + 1) { //prvo za maksimum: int x = niz[br]; int indeks_maks = 0; while(!s.empty() && s.top().Y <= x) s.pop(); if(!s.empty()) indeks_maks = s.top().X; s.push(make_pair(br, x)); //TODO: updateaj tournamnet: update(indeks_maks + 1, i, x) update(1, 0, off - 1, indeks_maks + 1, br, x); //sada za gcd: REP(i, (int) v.size()) { v[i].Y = gcd(v[i].Y, x); } v.push_back(par(br, x)); vector novi; REP(i, (int) v.size()) { if(novi.empty() || novi.back().Y != v[i].Y) novi.push_back(v[i]); } v = novi; vector granice; REP(i, (int) v.size()) granice.push_back(v[i]); granice.push_back(make_pair(br + 1, 0)); //cout << "br = " << br << endl; REP(i, (int) granice.size() - 1) { int a = granice[i].X; int b = granice[i + 1].X - 1; int g = granice[i].Y; // cout << a << " " << b << ": " << g << endl; rj = add(rj, mul(g, query(1, 0, off - 1, a, b) % MOD)); } } printf("%d\n", rj); return 0; }