#line 1 "test/yc_1036_test.cpp" #define PROBLEM "https://yukicoder.me/problems/no/1036" #include #include #include #include #include #line 1 "DataStructure/foldable_queue.cpp" /** * @brief fold 可能キュー * @author えびちゃん */ #include #include #include template class foldable_queue { public: using size_type = size_t; using value_type = Monoid; private: std::stack M_front, M_back; value_type M_back_folded{}; void M_distribute_to_front() { if (!M_back.empty()) { M_front.push(std::move(M_back.top())); M_back.pop(); } while (!M_back.empty()) { M_back.top() += M_front.top(); M_front.push(std::move(M_back.top())); M_back.pop(); } M_back_folded = value_type{}; } public: size_type size() const { return M_front.size() + M_back.size(); } bool empty() const noexcept { return M_front.empty() && M_back.empty(); } void push(value_type const& x) { M_back.push(x); M_back_folded += M_back.top(); } template void emplace(Args&&... args) { M_back.emplace(std::forward(args)...); M_back_folded += M_back.top(); } void pop() { if (M_front.empty()) M_distribute_to_front(); M_front.pop(); } value_type fold() const { if (M_front.empty()) return M_back_folded; return M_front.top() + M_back_folded; } }; #line 10 "test/yc_1036_test.cpp" template class gcd_monoid { public: using value_type = Tp; private: value_type M_x = 0; public: gcd_monoid() = default; // identity gcd_monoid(value_type const& x): M_x(x) {} gcd_monoid& operator +=(gcd_monoid const& that) { M_x = std::gcd(M_x, that.M_x); return *this; } friend bool operator ==(gcd_monoid const& lhs, gcd_monoid const& rhs) { return lhs.M_x == rhs.M_x; } friend gcd_monoid operator +(gcd_monoid lhs, gcd_monoid const& rhs) { return lhs += rhs; } friend bool operator !=(gcd_monoid const& lhs, gcd_monoid const& rhs) { return !(lhs == rhs); } value_type const& get() const { return M_x; } }; int main() { size_t n; scanf("%zu", &n); std::vector a(n); for (auto& ai: a) scanf("%jd", &ai); foldable_queue> q; intmax_t res = n*(n+1)/2; for (size_t il = 0, ir = 0; il < n; ++il) { while (ir < n && (q.fold() + a[ir]).get() != 1) { q.push(a[ir++]); } res -= ir-il; if (ir == il) ++ir; else q.pop(); } printf("%jd\n", res); }