Advertisement
Guest User

Untitled

a guest
Oct 17th, 2017
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.45 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. #define FOR(i, a, b) for(int i = a; i < b; ++i)
  5. #define REP(i, n) FOR(i, 0, n)
  6. #define _ << " " <<
  7.  
  8. typedef long long ll;
  9. typedef pair<int, int> point;
  10.  
  11. const int MAXN = 1e5 + 5, LOG = 18, mod = 1e9 + 7;
  12.  
  13. int n;
  14. int a[MAXN], dp[MAXN];
  15. int lft[MAXN], rmq[MAXN][LOG], pot[MAXN];
  16.  
  17. int add(int x, int y) {
  18.   x += y;
  19.   if(x >= mod)
  20.     return x - mod;
  21.   return x;
  22. }
  23. int sub(int x, int y) {
  24.   x -= y;
  25.   if(x < 0)
  26.     return x + mod;
  27.   return x;
  28. }
  29. int mul(int x, int y) {
  30.   return (ll) x * y % mod;
  31. }
  32.  
  33. int get(int l, int r) {
  34.   if(l > r)
  35.     return 0;
  36.  
  37.   int ret = 0;
  38.   if(r >= 0)
  39.     ret = add(ret, dp[r]);
  40.   if(l > 0)
  41.     ret = sub(ret, dp[l - 1]);
  42.   return ret;
  43. }
  44.  
  45. void calc(int x) {
  46.   REP(i, n) {
  47.     dp[i] = get(lft[i] - 1, i - 1);
  48.     if(!lft[i] && i <= x) {
  49.       dp[i] = add(dp[i], 1);
  50.     }
  51.     dp[i] = add(dp[i], dp[i - 1]);
  52.   }
  53. }
  54.  
  55. void load() {
  56.   cin >> n;
  57.   REP(i, n) {
  58.     cin >> a[i];
  59.   }
  60. }
  61.  
  62. int get_gcd(int l, int r) {
  63.   if(l == r)
  64.     return a[l];
  65.   int p = pot[r - l + 1] - 1;
  66.   return __gcd(rmq[r][p], rmq[l + (1 << p) - 1][p]);
  67. }
  68.  
  69. void preprocess() {
  70.   REP(i, n) {
  71.     rmq[i][0] = a[i];
  72.     FOR(j, 1, LOG) {
  73.       if(i + 1 < (1 << j))
  74.         break;
  75.       rmq[i][j] = __gcd(rmq[i][j - 1], rmq[i - (1 << (j - 1))][j - 1]);
  76.     }
  77.   }
  78.   int tmp = 0;
  79.   FOR(i, 1, MAXN) {
  80.     pot[i] = tmp;
  81.     if((1 << tmp) == i)
  82.       tmp ++;
  83.   }
  84.   REP(i, n) {
  85.     int lo = 0, hi = i;
  86.     while(lo < hi) {
  87.       int mid = (lo + hi) >> 1;
  88.       if(get_gcd(mid, i) == 1)
  89.         lo = mid + 1;
  90.       else
  91.         hi = mid;
  92.     }
  93.     lft[i] = lo;
  94.   }
  95. }
  96.  
  97. int get(int x) {
  98.   int lo = -1, hi = n - 1;
  99.   while(lo < hi) {
  100.     int mid = (lo + hi + 1) >> 1;
  101.     if(__gcd(get_gcd(0, mid), x) == 1)
  102.       hi = mid - 1;
  103.     else
  104.       lo = mid;
  105.   }
  106.   return lo;
  107. }
  108.  
  109. void solve() {
  110.   preprocess();
  111.   int sol = 0;
  112.  
  113.   if(!lft[n - 1]) {
  114.     sol = 1;
  115.     REP(i, n)
  116.       sol = mul(sol, 2);
  117.     sol = sub(sol, n);
  118.     cout << sol;
  119.     return;
  120.   }
  121.  
  122.   int gcdr = 0, l = -1;
  123.   REP(e, n) {
  124.     if(gcdr == 1)
  125.       break;
  126.  
  127.     int nl = get(gcdr);
  128.     if(nl == -1)
  129.       break;
  130.  
  131.     if(nl != l)
  132.       calc(nl);
  133.  
  134.     l = nl;
  135.     int Adding = dp[n - e - 1];
  136.     if(n - e - 1 != 0)
  137.       Adding = sub(Adding, dp[n - e - 2]);
  138.  
  139.     sol = add(sol, Adding);
  140.     gcdr = __gcd(gcdr, a[n - e - 1]);
  141.   }
  142.  
  143.   cout << sol;
  144. }
  145.  
  146. int main() {
  147.   load();
  148.   solve();
  149. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement