Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- using namespace std;
- #define FOR(i, a, b) for(int i = a; i < b; ++i)
- #define REP(i, n) FOR(i, 0, n)
- #define _ << " " <<
- typedef long long ll;
- typedef pair<int, int> point;
- const int MAXN = 1e5 + 5, LOG = 18, mod = 1e9 + 7;
- int n;
- int a[MAXN], dp[MAXN];
- int lft[MAXN], rmq[MAXN][LOG], pot[MAXN];
- int add(int x, int y) {
- x += y;
- if(x >= mod)
- return x - mod;
- return x;
- }
- int sub(int x, int y) {
- x -= y;
- if(x < 0)
- return x + mod;
- return x;
- }
- int mul(int x, int y) {
- return (ll) x * y % mod;
- }
- int get(int l, int r) {
- if(l > r)
- return 0;
- int ret = 0;
- if(r >= 0)
- ret = add(ret, dp[r]);
- if(l > 0)
- ret = sub(ret, dp[l - 1]);
- return ret;
- }
- void calc(int x) {
- REP(i, n) {
- dp[i] = get(lft[i] - 1, i - 1);
- if(!lft[i] && i <= x) {
- dp[i] = add(dp[i], 1);
- }
- dp[i] = add(dp[i], dp[i - 1]);
- }
- }
- void load() {
- cin >> n;
- REP(i, n) {
- cin >> a[i];
- }
- }
- int get_gcd(int l, int r) {
- if(l == r)
- return a[l];
- int p = pot[r - l + 1] - 1;
- return __gcd(rmq[r][p], rmq[l + (1 << p) - 1][p]);
- }
- void preprocess() {
- REP(i, n) {
- rmq[i][0] = a[i];
- FOR(j, 1, LOG) {
- if(i + 1 < (1 << j))
- break;
- rmq[i][j] = __gcd(rmq[i][j - 1], rmq[i - (1 << (j - 1))][j - 1]);
- }
- }
- int tmp = 0;
- FOR(i, 1, MAXN) {
- pot[i] = tmp;
- if((1 << tmp) == i)
- tmp ++;
- }
- REP(i, n) {
- int lo = 0, hi = i;
- while(lo < hi) {
- int mid = (lo + hi) >> 1;
- if(get_gcd(mid, i) == 1)
- lo = mid + 1;
- else
- hi = mid;
- }
- lft[i] = lo;
- }
- }
- int get(int x) {
- int lo = -1, hi = n - 1;
- while(lo < hi) {
- int mid = (lo + hi + 1) >> 1;
- if(__gcd(get_gcd(0, mid), x) == 1)
- hi = mid - 1;
- else
- lo = mid;
- }
- return lo;
- }
- void solve() {
- preprocess();
- int sol = 0;
- if(!lft[n - 1]) {
- sol = 1;
- REP(i, n)
- sol = mul(sol, 2);
- sol = sub(sol, n);
- cout << sol;
- return;
- }
- int gcdr = 0, l = -1;
- REP(e, n) {
- if(gcdr == 1)
- break;
- int nl = get(gcdr);
- if(nl == -1)
- break;
- if(nl != l)
- calc(nl);
- l = nl;
- int Adding = dp[n - e - 1];
- if(n - e - 1 != 0)
- Adding = sub(Adding, dp[n - e - 2]);
- sol = add(sol, Adding);
- gcdr = __gcd(gcdr, a[n - e - 1]);
- }
- cout << sol;
- }
- int main() {
- load();
- solve();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement