#include #define rep(i,a,b) for (int i=a; i PII; typedef vector VI; typedef long long ll; typedef long double ld; const int T = 1<<18; const ll mod = 1e9+7; int tree[T+T], A[T], n; ll sum[T+T], lazy[T+T]; int gcdRead(int l, int r) { l+=T; r+=T; int ret = tree[l]; while (l=0LL) { lazy[a*2] = lazy[a]; lazy[a*2+1] = lazy[a]; } up(a*2, lewy, mitte); up(a*2+1, mitte+1, prawy); lazy[a] = -1LL; sum[a] = sum[a*2]+sum[a*2+1] % mod; } else up(a, lewy, prawy); } void ustaw (int left, int right, ll x, int a=1, int lewy=0, int prawy = n-1) { update(a, lewy, prawy); if (left<=lewy && right>=prawy) lazy[a] = x; else { if (left<=mitte) ustaw(left, right, x, a*2, lewy, mitte); if (right>mitte) ustaw(left, right, x, a*2+1, mitte+1, prawy); } update(a, lewy, prawy); } ll sumRead (int left, int right, int a=1, int lewy = 0, int prawy = n-1) { update(a, lewy, prawy); if (left<=lewy && right>=prawy) return sum[a]; else { ll ret = 0LL; if (left<=mitte) ret+=sumRead(left, right, a*2, lewy, mitte); if (right>mitte) ret+=sumRead(left, right, a*2+1, mitte+1, prawy); if (ret>=mod) ret-=mod; return ret; } } int main () { scanf ("%d", &n); rep(i,0,n) scanf ("%d", &A[i]); rep(i,0,n) tree[T+i] = A[i]; for (int t = T-1; t>0; t--) tree[t] = __gcd(tree[t*2], tree[t*2+1]); ll res = 0LL; //ostatni mniejszy niz ja for (int pos=n-1; pos>=0; pos--) { int l = pos, r = n-1; while (l= ll(A[pos])) r = mid; else l = mid+1; } ustaw(pos, l, A[pos]); //moje nowe maksimum ll g = A[pos]; int left = pos, right = pos; while (left