Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <vector>
- #include <map>
- #include <set>
- #include <queue>
- #include <algorithm>
- #include <string>
- #include <cmath>
- #include <cstdio>
- #include <iomanip>
- #include <fstream>
- #include <cassert>
- #include <cstring>
- #include <unordered_set>
- #include <unordered_map>
- #include <numeric>
- #include <ctime>
- #include <bitset>
- #include <complex>
- #include <random>
- using namespace std;
- typedef long long ll;
- typedef unsigned long long ull;
- #ifdef DEBUG
- const int MAXN = 10;
- const int MAXLOG = 4;
- const int MAXSQRT = 4;
- #else
- const int MAXN = 3e5;
- const int MAXLOG = 20;
- const int MAXSQRT = 400;
- #define cerr if (false) cerr
- #endif
- mt19937 rng(time(0));
- const int INF = 1e9;
- const int MOD = 1e9 + 7;
- int n;
- int ans = 0;
- int val[MAXN];
- int sparse[MAXN][MAXLOG];
- int precalc[MAXN];
- vector<int> border[MAXN];
- vector<int> color[MAXN];
- vector<int> border_1[MAXN];
- vector<int> color_1[MAXN];
- void build() {
- for (int i = 0; i < n; i++) {
- sparse[i][0] = val[i];
- }
- for (int i = 1; i < MAXLOG; i++) {
- for (int j = 0; (j + (1 << i)) <= MAXN; j++) {
- sparse[j][i] = min(sparse[j][i - 1], sparse[j + (1 << (i - 1))][i - 1]);
- }
- }
- }
- int get(int l, int r) {
- int lg = precalc[r - l + 1];
- return min(sparse[l][lg], sparse[r - (1 << lg) + 1][lg]);
- }
- int nxt(int x, int pos) {
- int l = pos + 1;
- int r = n;
- while (l + 1 < r) {
- int mid = (l + r) >> 1;
- if (get(pos + 1, mid) <= x) {
- r = mid;
- }
- else {
- l = mid;
- }
- }
- return r;
- }
- int prv(int x, int pos) {
- int r = pos - 1;
- int l = -1;
- while (l + 1 < r) {
- int mid = (l + r) >> 1;
- if (get(mid, pos - 1) <= x) {
- l = mid;
- }
- else {
- r = mid;
- }
- }
- return l;
- }
- int get_color(int pos, int start) {
- int l = 0;
- int r = border_1[start].size();
- while (l + 1 < r) {
- int mid = (l + r) >> 1;
- if (border_1[start][mid] <= pos) {
- l = mid;
- }
- else {
- r = mid;
- }
- }
- return color[start][l];
- }
- int check(int position, int level) {
- int ret = 0;
- {
- int l = (level == 0 ? position : border[position][level - 1] + 1);
- int r = border[position][level];
- while (l + 1 < r) {
- int mid = (l + r) >> 1;
- if (get_color(position, mid) < color[position][level]) {
- l = mid;
- }
- else {
- r = mid;
- }
- }
- ret -= r;
- }
- {
- int l = (level == 0 ? position : border[position][level - 1] + 1);
- int r = border[position][level];
- while (l + 1 < r) {
- int mid = (l + r) >> 1;
- if (get_color(position, mid) <= color[position][level]) {
- l = mid;
- }
- else {
- r = mid;
- }
- }
- ret += r;
- }
- return ret;
- }
- inline void init() {
- precalc[1] = 0;
- for (int i = 2; i < MAXN; i++) {
- precalc[i] = precalc[i >> 1] + 1;
- }
- ans = 0;
- }
- inline void solve() {
- init();
- for (int i = 0; i < n; i++) {
- cin >> val[i];
- }
- build();
- for (int i = 0; i < n; i++) {
- int pnt = 0;
- int cur = val[i];
- int pos = i;
- while (pos < n) {
- pos = nxt(cur, pos);
- color[i].push_back(cur);
- border[i].push_back(pos - 1);
- if (pos != n) {
- cur = cur % val[pos];
- }
- }
- }
- for (int i = n - 1; i >= 0; i--) {
- int pnt = 0;
- int cur = val[i];
- int pos = i;
- while (pos >= 0) {
- pos = prv(cur, pos);
- color_1[i].push_back(cur);
- border_1[i].push_back(pos + 1);
- if (pos != -1) {
- cur = cur % val[pos];
- }
- }
- }
- for (int i = 0; i < n; i++) {
- int last = i;
- for (int j = 0; j < color[i].size(); j++) {
- ans += check(i, j);
- }
- }
- cout << ans << '\n';
- }
- signed main() {
- #ifdef DEBUG
- freopen("I.in", "r", stdin);
- freopen("I.out", "w", stdout);
- #else
- #endif
- ios_base::sync_with_stdio(0);
- cin.tie(0);
- cout.tie(0);
- while (cin >> n)
- solve();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement