Advertisement
KiK0S

Untitled

Mar 20th, 2019
224
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.72 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <map>
  4. #include <set>
  5. #include <queue>
  6. #include <algorithm>
  7. #include <string>
  8. #include <cmath>
  9. #include <cstdio>
  10. #include <iomanip>
  11. #include <fstream>
  12. #include <cassert>
  13. #include <cstring>
  14. #include <unordered_set>
  15. #include <unordered_map>
  16. #include <numeric>
  17. #include <ctime>
  18. #include <bitset>
  19. #include <complex>
  20. #include <random>
  21. using namespace std;
  22.  
  23. typedef long long ll;
  24. typedef unsigned long long ull;
  25.  
  26. #ifdef DEBUG
  27.     const int MAXN = 10;
  28.     const int MAXLOG = 4;
  29.     const int MAXSQRT = 4;
  30. #else
  31.     const int MAXN = 3e5;
  32.     const int MAXLOG = 20;
  33.     const int MAXSQRT = 400;
  34.     #define cerr if (false) cerr
  35. #endif
  36.  
  37. mt19937 rng(time(0));
  38.  
  39. const int INF = 1e9;
  40. const int MOD = 1e9 + 7;
  41.  
  42. int n;
  43. int ans = 0;
  44.  
  45. int val[MAXN];
  46. int sparse[MAXN][MAXLOG];
  47. int precalc[MAXN];
  48. vector<int> border[MAXN];
  49. vector<int> color[MAXN];
  50. vector<int> border_1[MAXN];
  51. vector<int> color_1[MAXN];
  52.  
  53. void build() {
  54.     for (int i = 0; i < n; i++) {
  55.         sparse[i][0] = val[i];
  56.     }
  57.     for (int i = 1; i < MAXLOG; i++) {
  58.         for (int j = 0; (j + (1 << i)) <= MAXN; j++) {
  59.             sparse[j][i] = min(sparse[j][i - 1], sparse[j + (1 << (i - 1))][i - 1]);
  60.         }
  61.     }
  62. }
  63.  
  64. int get(int l, int r) {
  65.     int lg = precalc[r - l + 1];
  66.     return min(sparse[l][lg], sparse[r - (1 << lg) + 1][lg]);
  67. }
  68.  
  69. int nxt(int x, int pos) {
  70.     int l = pos + 1;
  71.     int r = n;
  72.     while (l + 1 < r) {
  73.         int mid = (l + r) >> 1;
  74.         if (get(pos + 1, mid) <= x) {
  75.             r = mid;
  76.         }
  77.         else {
  78.             l = mid;
  79.         }
  80.     }
  81.     return r;
  82. }
  83.  
  84. int prv(int x, int pos) {
  85.     int r = pos - 1;
  86.     int l = -1;
  87.     while (l + 1 < r) {
  88.         int mid = (l + r) >> 1;
  89.         if (get(mid, pos - 1) <= x) {
  90.             l = mid;
  91.         }
  92.         else {
  93.             r = mid;
  94.         }
  95.     }
  96.     return l;
  97. }
  98.  
  99. int get_color(int pos, int start) {
  100.     int l = 0;
  101.     int r = border_1[start].size();
  102.     while (l + 1 < r) {
  103.         int mid = (l + r) >> 1;
  104.         if (border_1[start][mid] <= pos) {
  105.             l = mid;
  106.         }
  107.         else {
  108.             r = mid;
  109.         }
  110.     }
  111.     return color[start][l];
  112. }
  113.  
  114. int check(int position, int level) {
  115.     int ret = 0;
  116.     {
  117.         int l = (level == 0 ? position : border[position][level - 1] + 1);
  118.         int r = border[position][level];
  119.         while (l + 1 < r) {
  120.             int mid = (l + r) >> 1;
  121.             if (get_color(position, mid) < color[position][level]) {
  122.                 l = mid;
  123.             }
  124.             else {
  125.                 r = mid;
  126.             }
  127.         }
  128.         ret -= r;
  129.     }
  130.     {
  131.         int l = (level == 0 ? position : border[position][level - 1] + 1);
  132.         int r = border[position][level];
  133.         while (l + 1 < r) {
  134.             int mid = (l +   r) >> 1;
  135.             if (get_color(position, mid) <= color[position][level]) {
  136.                 l = mid;
  137.             }
  138.             else {
  139.                 r = mid;
  140.             }
  141.         }
  142.         ret += r;
  143.     }
  144.     return ret;
  145. }
  146.  
  147.  
  148. inline void init() {
  149.     precalc[1] = 0;
  150.     for (int i = 2; i < MAXN; i++) {
  151.         precalc[i] = precalc[i >> 1] + 1;
  152.     }
  153.     ans = 0;
  154. }
  155.  
  156. inline void solve() {
  157.     init();
  158.     for (int i = 0; i < n; i++) {
  159.         cin >> val[i];
  160.     }
  161.     build();
  162.     for (int i = 0; i < n; i++) {
  163.         int pnt = 0;
  164.         int cur = val[i];
  165.         int pos = i;
  166.         while (pos < n) {
  167.             pos = nxt(cur, pos);
  168.             color[i].push_back(cur);
  169.             border[i].push_back(pos - 1);
  170.             if (pos != n) {
  171.                 cur = cur % val[pos];
  172.             }
  173.         }
  174.     }
  175.     for (int i = n - 1; i >= 0; i--) {
  176.         int pnt = 0;
  177.         int cur = val[i];
  178.         int pos = i;
  179.         while (pos >= 0) {
  180.             pos = prv(cur, pos);
  181.             color_1[i].push_back(cur);
  182.             border_1[i].push_back(pos + 1);
  183.             if (pos != -1) {
  184.                 cur = cur % val[pos];
  185.             }
  186.         }
  187.     }
  188.  
  189.     for (int i = 0; i < n; i++) {
  190.         int last = i;
  191.         for (int j = 0; j < color[i].size(); j++) {
  192.             ans += check(i, j);
  193.         }
  194.     }
  195.     cout << ans << '\n';
  196. }
  197.  
  198. signed main() {
  199.     #ifdef DEBUG
  200.         freopen("I.in", "r", stdin);
  201.         freopen("I.out", "w", stdout);
  202.     #else
  203.    
  204.     #endif
  205.     ios_base::sync_with_stdio(0);
  206.     cin.tie(0);
  207.     cout.tie(0);
  208.     while (cin >> n)
  209.         solve();
  210.     return 0;
  211. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement