結果
問題 | No.1036 Make One With GCD 2 |
ユーザー |
![]() |
提出日時 | 2020-04-24 21:57:09 |
言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 1,276 ms / 2,000 ms |
コード長 | 4,253 bytes |
コンパイル時間 | 1,263 ms |
コンパイル使用メモリ | 116,256 KB |
実行使用メモリ | 15,368 KB |
最終ジャッジ日時 | 2024-09-16 13:14:51 |
合計ジャッジ時間 | 17,749 ms |
ジャッジサーバーID (参考情報) |
judge6 / judge3 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 4 |
other | AC * 41 |
ソースコード
#include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cmath>#include <vector>#include <set>#include <map>#include <unordered_set>#include <unordered_map>#include <queue>#include <ctime>#include <cassert>#include <complex>#include <string>#include <cstring>#include <chrono>#include <random>#include <queue>#include <bitset>#include <stack>#include <functional>#ifdef LOCAL#define eprintf(...) fprintf(stderr, __VA_ARGS__)#else#define eprintf(...) 42#endif#define rep_(i, a_, b_, a, b, ...) for (int i = (a), i##_len = (b); i < i##_len; ++i)#define rep(i, ...) rep_(i, __VA_ARGS__, __VA_ARGS__, 0, __VA_ARGS__)#define reprev_(i, a_, b_, a, b, ...) for (int i = (b-1), i##_min = (a); i >= i##_min; --i)#define reprev(i, ...) reprev_(i, __VA_ARGS__, __VA_ARGS__, 0, __VA_ARGS__)#define all(x) (x).begin(), (x).end()template <class T> bool chmax(T &a, const T &b) { if (a < b) { a = b; return 1; } return 0; }template <class T> bool chmin(T &a, const T &b) { if (b < a) { a = b; return 1; } return 0; }template <class T> T gcd(T a, T b) { return b ? gcd(b, a % b) : a; }using namespace std;typedef long long ll;typedef unsigned long long ull;typedef pair <int,int> P;typedef long double ld;template< typename Monoid >struct SegmentTree {using F = function< Monoid(Monoid, Monoid) >;int sz;vector< Monoid > seg;const F f;const Monoid M1;SegmentTree(int n, const F f, const Monoid &M1) : f(f), M1(M1) {sz = 1;while(sz < n) sz <<= 1;seg.assign(2 * sz, M1);}void set(int k, const Monoid &x) {seg[k + sz] = x;}void build() {for(int k = sz - 1; k > 0; k--) {seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);}}void update(int k, const Monoid &x) {k += sz;seg[k] = x;while(k >>= 1) {seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);}}Monoid query(int a, int b) {Monoid L = M1, R = M1;for(a += sz, b += sz; a < b; a >>= 1, b >>= 1) {if(a & 1) L = f(L, seg[a++]);if(b & 1) R = f(seg[--b], R);}return f(L, R);}Monoid operator[](const int &k) const {return seg[k + sz];}template< typename C >int find_subtree(int a, const C &check, Monoid &M, bool type) {while(a < sz) {Monoid nxt = type ? f(seg[2 * a + type], M) : f(M, seg[2 * a + type]);if(check(nxt)) a = 2 * a + type;else M = nxt, a = 2 * a + 1 - type;}return a - sz;}template< typename C >int find_first(int a, const C &check) {Monoid L = M1;if(a <= 0) {if(check(f(L, seg[1]))) return find_subtree(1, check, L, false);return -1;}int b = sz;for(a += sz, b += sz; a < b; a >>= 1, b >>= 1) {if(a & 1) {Monoid nxt = f(L, seg[a]);if(check(nxt)) return find_subtree(a, check, L, false);L = nxt;++a;}}return -1;}template< typename C >int find_last(int b, const C &check) {Monoid R = M1;if(b >= sz) {if(check(f(seg[1], R))) return find_subtree(1, check, R, true);return -1;}int a = sz;for(b += sz; a < b; a >>= 1, b >>= 1) {if(b & 1) {Monoid nxt = f(seg[--b], R);if(check(nxt)) return find_subtree(b, check, R, true);R = nxt;}}return -1;}};int main (void){cin.tie(0);ios::sync_with_stdio(false);int n; cin >> n;SegmentTree<ll> seg(n, [](ll a, ll b){return gcd(a, b);}, 0LL);vector<ll> a(n);rep (i, n) {cin >> a[i]; seg.update(i, a[i]);}ll ans = 0;int l = 0, r = 1;for (l = 0; l < n; l++) {ll g = seg.query(l, r);while (r < n && g > 1) g = gcd(a[r++], g);if (r > n || g > 1) break;ans += (ll)n - r + 1;eprintf("%d %d %lld\n", l, r, g);if (l + 1 == r) r++;}cout << ans << "\n";return 0;}