結果

問題 No.1036 Make One With GCD 2
ユーザー noshi91noshi91
提出日時 2020-04-25 17:30:41
言語 C++17
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 1,179 ms / 2,000 ms
コード長 3,375 bytes
コンパイル時間 953 ms
コンパイル使用メモリ 84,072 KB
実行使用メモリ 81,408 KB
最終ジャッジ日時 2024-04-25 00:58:24
合計ジャッジ時間 24,806 ms
ジャッジサーバーID
(参考情報)
judge2 / judge3
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 622 ms
81,280 KB
testcase_01 AC 645 ms
81,152 KB
testcase_02 AC 183 ms
81,280 KB
testcase_03 AC 39 ms
30,336 KB
testcase_04 AC 69 ms
52,992 KB
testcase_05 AC 2 ms
5,376 KB
testcase_06 AC 2 ms
5,376 KB
testcase_07 AC 203 ms
34,560 KB
testcase_08 AC 168 ms
28,800 KB
testcase_09 AC 729 ms
79,360 KB
testcase_10 AC 690 ms
73,728 KB
testcase_11 AC 744 ms
81,024 KB
testcase_12 AC 711 ms
74,368 KB
testcase_13 AC 1,179 ms
77,568 KB
testcase_14 AC 1,157 ms
78,336 KB
testcase_15 AC 1,083 ms
73,344 KB
testcase_16 AC 1,099 ms
73,984 KB
testcase_17 AC 1,137 ms
76,416 KB
testcase_18 AC 2 ms
5,376 KB
testcase_19 AC 3 ms
5,376 KB
testcase_20 AC 4 ms
5,376 KB
testcase_21 AC 3 ms
5,376 KB
testcase_22 AC 1,060 ms
72,576 KB
testcase_23 AC 787 ms
53,376 KB
testcase_24 AC 1,116 ms
75,648 KB
testcase_25 AC 1,017 ms
68,864 KB
testcase_26 AC 1,052 ms
71,296 KB
testcase_27 AC 1 ms
5,376 KB
testcase_28 AC 1 ms
5,376 KB
testcase_29 AC 2 ms
5,376 KB
testcase_30 AC 1 ms
5,376 KB
testcase_31 AC 1 ms
5,376 KB
testcase_32 AC 2 ms
5,376 KB
testcase_33 AC 2 ms
5,376 KB
testcase_34 AC 2 ms
5,376 KB
testcase_35 AC 2 ms
5,376 KB
testcase_36 AC 1 ms
5,376 KB
testcase_37 AC 2 ms
5,376 KB
testcase_38 AC 183 ms
81,408 KB
testcase_39 AC 739 ms
81,280 KB
testcase_40 AC 780 ms
53,376 KB
testcase_41 AC 815 ms
81,408 KB
testcase_42 AC 812 ms
81,280 KB
testcase_43 AC 700 ms
81,408 KB
testcase_44 AC 764 ms
81,280 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#define NDEBUG
#include <cassert>
#include <utility>
#include <vector>

template <class Semigroup> class disjoint_sparse_table {
public:
  using value_structure = Semigroup;
  using value_type = typename value_structure::value_type;

private:
  using container_type = ::std::vector<::std::vector<value_type>>;

public:
  using const_reference = typename container_type::value_type::const_reference;
  using size_type = typename container_type::value_type::size_type;

protected:
  static size_type msb(size_type c) {
#ifdef __has_builtin
    return 31 - __builtin_clz(c);
#else
    ::std::size_t ret = 0;
    if (c >> 16)
      c >>= 16, ret += 16;
    if (c >> 8)
      c >>= 8, ret += 8;
    if (c >> 4)
      c >>= 4, ret += 4;
    if (c >> 2)
      c >>= 2, ret += 2;
    return ret + (c >> 1);
#endif
  }

  container_type table;

public:
  disjoint_sparse_table() : table() {}
  template <class InputIterator>
  disjoint_sparse_table(InputIterator first, InputIterator last) : table() {
    table.emplace_back(first, last);
    const size_type size = table.front().size();
    for (size_type i = 2; i < size; i <<= 1) {
      typename container_type::value_type v;
      v.reserve(size);
      for (size_type j = i; j < size; j += i << 1) {
        v.emplace_back(table.front()[j - 1]);
        for (size_type k = 2; k <= i; ++k)
          v.emplace_back(
              value_structure::operation(table.front()[j - k], v.back()));
        v.emplace_back(table.front()[j]);
        for (size_type k = 1; k < i && j + k < size; ++k)
          v.emplace_back(
              value_structure::operation(v.back(), table.front()[j + k]));
      }
      table.emplace_back(::std::move(v));
    }
  }

  size_type size() const { return table.empty() ? 0 : table.front().size(); }
  bool empty() const { return size() == 0; }

  value_type fold_closed(const size_type first, const size_type last) const {
    assert(first <= last);
    assert(last < size());
    if (first == last) {
      return table.front()[first];
    } else {
      const size_type p = msb(first ^ last);
      return value_structure::operation(
          table[p][first ^ (static_cast<size_type>(1) << p) - 1],
          table[p][last]);
    }
  }
  const_reference operator[](const size_type index) const {
    assert(index < size());
    return table.front()[index];
  }
};

#include <iostream>
#include <numeric>
#include <vector>

using u64 = unsigned long long;

class gcd_monoid {
public:
  using value_type = u64;
  static constexpr u64 operation(const u64 a, const u64 b) {
    return std::gcd(a, b);
  }
  static constexpr u64 identity = 0;
};

int main() {
  std::cin.tie(nullptr);
  std::ios::sync_with_stdio(false);

  int n;
  std::cin >> n;
  std::vector<u64> as(n);
  for (int i = 0; i < n; i++)
    std::cin >> as[i];

  const disjoint_sparse_table<gcd_monoid> dst(as.begin(), as.end());

  u64 ans = 0;
  for (int i = 0; i < n; i++) {
    int l = i;
    u64 pre = as[i], lst = dst.fold_closed(i, n - 1);
    while (lst != pre) {
      int r = n, pl = l;
      while (l + 1 < r) {
        int m = (l + r) >> 1;
        if (dst.fold_closed(i, m - 1) != pre)
          r = m;
        else
          l = m;
      }
      if (pre == 1)
        ans += l - pl;
      pre = dst.fold_closed(i, r - 1);
    }
    if (lst == 1)
      ans += n - l;
  }

  std::cout << ans << std::endl;
  return 0;
}
0