#include #define FOR(i, n) for(int i = 0; i < (n); ++i) #define REP(i, a, b) for(int i = (a); i < (b); ++i) #define TRAV(i, a) for(auto &i : (a)) #define X first #define Y second #define st first #define nd second #define MP std::make_pair #define PR std::pair #define SZ(x) ((int)(x).size()) typedef long long ll; typedef std::pair PII; typedef std::vector VI; using namespace std; const int N=2e5+5; const int MOD = 1000000007; int t[N]; vector wlewo[N], wprawo[N]; //para indeks, wartosc gcd int n; void licz(){ for(int i=n; i>=1; i--){ wprawo[i].push_back({i, t[i]}); for(auto &x: wprawo[i+1]){ int val=__gcd(x.nd, wprawo[i].back().nd); if(val==wprawo[i].back().nd) wprawo[i].back().st=x.st; else wprawo[i].push_back({x.st, val}); } } for(int i=1; i<=n; i++){ wlewo[i].push_back({i, t[i]}); for(auto &x: wlewo[i-1]){ int val=__gcd(x.nd, wlewo[i].back().nd); if(val==wlewo[i].back().nd) wlewo[i].back().st=x.st; else wlewo[i].push_back({x.st, val}); } } } struct Tree{ int BOTTOM; std::vector t; void build(VI A){ BOTTOM = 1; while(BOTTOM < SZ(A)) BOTTOM *= 2; t.resize(2*BOTTOM, MP(0, -1)); FOR(i, SZ(A)) t[i+BOTTOM] = MP(A[i], i); for(int i = BOTTOM-1; i >= 1; --i) t[i] = std::max(t[i<<1], t[(i<<1)+1]); } PII query(int a, int b){ a += BOTTOM; b += BOTTOM+1; PII mx = MP(0, -1); while(a < b){ if(a&1) mx = std::max(mx, t[a++]); if(b&1) mx = std::max(mx, t[--b]); a>>=1; b>>=1; } return mx; } void update(int a, int what){ a += BOTTOM; t[a].X = what; while(a > 1){ a >>= 1; t[a] = std::max(t[a<<1], t[(a<<1)+1]); } } }; int ans; Tree tree; int modpow(int a, int e){ int ret = 1; while(e > 0){ if(e&1) ret = (1ll*ret*a)%MOD; a = (1ll*a*a)%MOD; e >>= 1; } return ret; } void solve(int a, int b){ if(a > b) return; auto xdd = tree.query(a, b); int mx = xdd.X; int mid = xdd.Y; if(mid - a < b - mid){ // w lewo ide po jednym int pos = mid; while(pos >= a){ int last = mid-1; TRAV(pr, wprawo[pos]){ int ile = std::max(0, std::min(b, pr.X)-last); int mul = (1ll*pr.Y*mx)%MOD; mul = (1ll*mul*ile)%MOD; ans += mul; if(ans >= MOD) ans -= MOD; last = std::max(last, pr.X); if(last >= b) break; } pos--; } }else{ int pos = mid; while(pos <= b){ int last = mid+1; TRAV(pr, wlewo[pos]){ int ile = std::max(0, last-std::max(a, pr.X)); int mul = (1ll*pr.Y*mx)%MOD; mul = (1ll*mul*ile)%MOD; ans += mul; if(ans >= MOD) ans -= MOD; last = std::min(pr.X, last); if(last <= a) break; } pos++; } } solve(a, mid-1); solve(mid+1, b); } int main(){ std::ios_base::sync_with_stdio(false); std::cin.tie(0); std::cin >> n; VI A(n+1); FOR(i, n){ std::cin >> A[i+1]; t[i+1] = A[i+1]; } licz();/* REP(i, 1, n+1){ std::cout << "pos " << i << std::endl; TRAV(pr, wlewo[i]){ std::cout << pr.X << " " << pr.Y << " "; } std::cout << std::endl; }*/ tree.build(A); solve(1, n); std::cout << ans; return 0; }