結果
問題 | No.1036 Make One With GCD 2 |
ユーザー |
![]() |
提出日時 | 2020-12-03 15:39:50 |
言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 483 ms / 2,000 ms |
コード長 | 4,536 bytes |
コンパイル時間 | 1,857 ms |
コンパイル使用メモリ | 178,260 KB |
実行使用メモリ | 15,652 KB |
最終ジャッジ日時 | 2024-09-16 14:30:36 |
合計ジャッジ時間 | 13,224 ms |
ジャッジサーバーID (参考情報) |
judge6 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 4 |
other | AC * 41 |
ソースコード
#include <bits/stdc++.h>#define rep(i, n) for(int(i) = 0; (i) < (n); (i)++)#define FOR(i, m, n) for(int(i) = (m); (i) < (n); (i)++)#define ALL(v) (v).begin(), (v).end()#define LLA(v) (v).rbegin(), (v).rend()#define PB push_back#define MP(a, b) make_pair((a), (b))using namespace std;template <class T> inline vector<T> make_vec(size_t a, T val) {return vector<T>(a, val);}template <class... Ts> inline auto make_vec(size_t a, Ts... ts) {return vector<decltype(make_vec(ts...))>(a, make_vec(ts...));}template <typename T> inline T read() {T t;cin >> t;return t;}template <typename T> inline vector<T> readv(size_t sz) {vector<T> ret(sz);rep(i, sz) cin >> ret[i];return ret;}template <typename... Ts> inline tuple<Ts...> reads() {return {read<Ts>()...};}template <typename T> struct edge {int to;T cost;edge(int t, T c) : to(t), cost(c) {}};using ll = long long;using pii = pair<int, int>;using pll = pair<ll, ll>;using Graph = vector<vector<int>>;template <typename T> using WGraph = vector<vector<edge<T>>>;const int INF = 1 << 30;const ll LINF = 1LL << 60;const int MOD = 1e9 + 7;/* SegmentTree(0-indexed) */template <class Monoid> struct SegmentTree {using F = function<Monoid(Monoid, Monoid)>;const F f;const Monoid e;int n;vector<Monoid> dat;SegmentTree(int _n, const F _f, const Monoid &_e) : f(_f), e(_e) {n = 1;while(n < _n)n *= 2;dat.assign(2 * n, e);}SegmentTree(vector<Monoid> v, const F _f, const Monoid &_e) : f(_f), e(_e) {int sz = v.size();n = 1;while(n < sz)n *= 2;dat.resize(2 * n);for(int i = 0; i < sz; i++)set(i, v[i]);build();}void set(int k, Monoid a) { dat[k + n] = a; }void build() {for(int i = n - 1; i > 0; i--) {dat[i] = f(dat[2 * i], dat[2 * i + 1]);}}void update(int k, const Monoid &a) {k += n;dat[k] += a;while(k >>= 1) {dat[k] = f(dat[k * 2], dat[k * 2 + 1]);}}Monoid at(int a) { return query(a, a + 1); }// query for [a,b)Monoid query(int a, int b) {Monoid vl = e, vr = e;a += n, b += n;for(; a < b; a >>= 1, b >>= 1) {if(a & 1)vl = f(vl, dat[a++]);if(b & 1)vr = f(dat[--b], vr);}return f(vl, vr);}};template <class T> struct RgcdQ : SegmentTree<T> {using Segtree = SegmentTree<T>;static auto f(T a, T b) { return __gcd(a, b); }RgcdQ(ll n, const T &e = 0) : Segtree(n, f, e) {}RgcdQ(const vector<T> &A, const T &e = 0) : Segtree(A, f, e) {}};template <typename SemiGroup> class SlidingWindowAggregation {public:using F = function<SemiGroup(SemiGroup, SemiGroup)>;SlidingWindowAggregation(F f) : f(f) {}const F f;stack<pair<SemiGroup, SemiGroup>> front, back;bool empty() { return front.empty() && back.empty(); }size_t size() { return front.size() + back.size(); }SemiGroup fold_all() {assert(!this->empty());if(front.empty()) {return back.top().second;} else if(back.empty()) {return front.top().second;} else {return f(front.top().second, back.top().second);}}void push(const SemiGroup &x) {if(front.empty()) {front.emplace(x, x);} else {front.emplace(x, f(front.top().second, x));}}void pop() {if(back.empty()) {back.emplace(front.top().first, front.top().first);front.pop();while(!front.empty()) {back.emplace(front.top().first,f(front.top().first, back.top().second));front.pop();}}back.pop();}};ll f(ll a, ll b) { return __gcd(a, b); }int main() {ios::sync_with_stdio(false);cin.tie(nullptr);int N = read<int>();auto A = readv<ll>(N);SlidingWindowAggregation<ll> swag(f);ll res = 0;int right = 0;for(int left = 0; left < N; left++) {while(right < N && (swag.empty() || swag.fold_all() != 1)) {swag.push(A[right]);right++;}if(swag.fold_all() == 1)res += N - right + 1;swag.pop();}cout << res << endl;}