#include using namespace std; typedef long long ll; #define F first #define S second #define pii pair #define eb emplace_back #define all(v) v.begin(), v.end() #define rep(i, n) for (int i = 0; i < (n); ++i) #define rep3(i, l, n) for (int i = l; i < (n); ++i) #define sz(v) (int)v.size() #define endl '\n' const int inf = 1000000007; const ll INF = 1e18; // int mod = 998244353; int mod = 1000000007; #define abs(x) (x >= 0 ? x : -(x)) #define lb(v, x) (int)(lower_bound(all(v), x) - v.begin()) #define ub(v, x) (int)(upper_bound(all(v), x) - v.begin()) template inline bool chmin(T1 &a, T2 b) { if (a > b) { a = b; return 1; } return 0; } template inline bool chmax(T1 &a, T2 b) { if (a < b) { a = b; return 1; } return 0; } ll gcd(ll a, ll b) { if (b == 0) return a; return gcd(b, a % b); } ll lcm(ll a, ll b) { return a / gcd(a, b) * b; } ll pow(ll a, int b) { return b ? pow(a * a, b / 2) * (b % 2 ? a : 1) : 1; } ll modpow(ll a, ll b, ll _mod) { return b ? modpow(a * a % _mod, b / 2, _mod) * (b % 2 ? a : 1) % _mod : 1; } template ostream& operator << (ostream& os, const pair& p) { os << p.F << " " << p.S; return os; } template ostream& operator << (ostream& os, const vector& vec) { rep(i, sz(vec)) { if (i) os << " "; os << vec[i]; } return os; } template inline istream& operator >> (istream& is, vector& v) { rep(j, sz(v)) is >> v[j]; return is; } template inline void add(T &a, T2 b) { a += b; if (a >= mod) a -= mod; } void solve(); int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); cout << fixed << setprecision(10); int T; // cin >> T; T = 1; while (T--) { solve(); } } template class SegTree { int n; T def; vector data; function operation; // query で function update; // change で T _query(int a, int b, int k, int l, int r) { if (r <= a || b <= l) return def; if (a <= l && r <= b) return data[k]; T c1 = _query(a, b, 2 * k + 1, l, (l + r) / 2); T c2 = _query(a, b, 2 * k + 2, (l + r) / 2, r); return operation(c1, c2); } public: SegTree(int _n, T _def, function _operation, function _update) : def(_def), operation(_operation), update(_update) { n = 1; while (n < _n) n *= 2; data = vector(2 * n - 1, def); } T query(int a, int b) { return _query(a, b, 0, 0, n); } void change(int i, T x) { i += n - 1; data[i] = update(data[i], x); while (i > 0) { i = (i - 1) / 2; data[i] = operation(data[i * 2 + 1], data[i * 2 + 2]); } } T operator[](int i) { return data[i + n - 1]; } void out() { rep(i, n) cout << data[i + n - 1] << " "; cout << endl; } }; void solve() { int n; cin >> n; vector a(n); cin >> a; SegTree seg(n, 0, [](int a, int b) { return gcd(a, b); }, [](int a, int b) { return b; }); rep(i, n) seg.change(i, a[i]); set s; ll ans = 0; for (int i = n - 1; i >= 0; --i) { cout << "i " << i << endl; auto binary_search = [&](int ok, int ng) { while (abs(ng - ok) > 1) { int mid = (ng + ok) / 2; // cout << i << " " << mid << " " << seg.query(i, mid) << endl; (seg.query(i, mid + 1) > 1 ? ok : ng) = mid; } return ok; }; int it = binary_search(i, n); if (a[it] == 1) it = i - 1; // cout << it << endl; s.insert(it + 1); it = *s.lower_bound(i); // cout << it << endl; ans += n - it; } cout << ans << endl; }