結果
| 問題 | No.1036 Make One With GCD 2 |
| コンテスト | |
| ユーザー |
KoD
|
| 提出日時 | 2020-04-24 21:57:35 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
TLE
(最新)
AC
(最初)
|
| 実行時間 | - |
| コード長 | 4,566 bytes |
| コンパイル時間 | 3,850 ms |
| コンパイル使用メモリ | 78,032 KB |
| 最終ジャッジ日時 | 2025-01-09 23:40:57 |
|
ジャッジサーバーID (参考情報) |
judge3 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 4 |
| other | AC * 38 TLE * 3 |
コンパイルメッセージ
main.cpp: In function ‘int main()’:
main.cpp:179:8: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
179 | scanf("%d", &N);
| ~~~~~^~~~~~~~~~
main.cpp:182:10: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
182 | scanf("%lld", &x);
| ~~~~~^~~~~~~~~~~~
ソースコード
#include <iostream>
#include <algorithm>
#include <utility>
#include <vector>
#include <numeric>
template <class T, class U>
inline bool chmin(T &lhs, const U &rhs) {
if (lhs > rhs) {
lhs = rhs;
return true;
}
return false;
}
template <class T, class U>
inline bool chmax(T &lhs, const U &rhs) {
if (lhs < rhs) {
lhs = rhs;
return true;
}
return false;
}
// [l, r) from l to r
struct range {
struct itr {
int i;
constexpr itr(int i_): i(i_) { }
constexpr void operator ++ () { ++i; }
constexpr int operator * () const { return i; }
constexpr bool operator != (itr x) const { return i != x.i; }
};
const itr l, r;
constexpr range(int l_, int r_): l(l_), r(std::max(l_, r_)) { }
constexpr itr begin() const { return l; }
constexpr itr end() const { return r; }
};
// [l, r) from r to l
struct revrange {
struct itr {
int i;
constexpr itr(int i_): i(i_) { }
constexpr void operator ++ () { --i; }
constexpr int operator * () const { return i; }
constexpr bool operator != (itr x) const { return i != x.i; }
};
const itr l, r;
constexpr revrange(int l_, int r_): l(l_ - 1), r(std::max(l_, r_) - 1) { }
constexpr itr begin() const { return r; }
constexpr itr end() const { return l; }
};
template <class T>
class segment_tree {
public:
using value_type = typename T::value_type;
using effector_type = typename T::effector_type;
using value_operation = typename T::value_operation;
using merge_operation = typename T::merge_operation;
private:
int size;
const value_operation op1;
const merge_operation op2;
std::vector<value_type> node;
void update() {
for (int k = size - 1; k > 0; --k) {
node[k] = op1(node[k << 1 | 0], node[k << 1 | 1]);
}
}
public:
segment_tree(): op1(value_operation()), op2(merge_operation()) { }
segment_tree(int size_, const value_type &initial_ = value_operation().identity):
op1(value_operation()), op2(merge_operation())
{ init(size_, initial_); }
segment_tree(const std::vector<value_type> &node_):
op1(value_operation()), op2(merge_operation())
{ build(node_); }
void init(int size_, const value_type &initial_ = value_operation().identity) {
size = 1;
while (size < size_) {
size <<= 1;
}
node.assign(size << 1, initial_);
update();
}
void build(const std::vector<value_type> &node_) {
init(node_.size());
assign(node_.begin(), node_.end(), 0);
}
void modify(int i, const effector_type &x) {
i += size;
node[i] = op2(node[i], x);
while (i > 1) {
i >>= 1;
node[i] = op1(node[i << 1 | 0], node[i << 1 | 1]);
}
}
template <class U>
void modify(U begin, U end, int i) {
i += size;
while (begin != end) {
node[i] = op2(node[i], *begin);
++i;
++begin;
}
update();
}
void assign(int i, const value_type &x) {
i += size;
node[i] = x;
while (i > 1) {
i >>= 1;
node[i] = op1(node[i << 1 | 0], node[i << 1 | 1]);
}
}
template <class U>
void assign(U begin, U end, int i) {
i += size;
while (begin != end) {
node[i] = *begin;
++i;
++begin;
}
update();
}
value_type operator [] (int i) const {
return node[i + size];
}
value_type fold(int l, int r) const {
l += size;
r += size;
value_type resl = op1.identity;
value_type resr = op1.identity;
while (l < r) {
if (l & 1) {
resl = op1(resl, node[l++]);
}
if (r & 1) {
resr = op1(node[--r], resr);
}
l >>= 1;
r >>= 1;
}
return op1(resl, resr);
}
};
struct monoid {
using value_type = long long;
using effector_type = long long;
struct value_operation {
value_type identity = 0;
value_type operator () (const value_type &x, const value_type &y) const {
return std::gcd(x, y);
}
};
struct merge_operation {
value_type operator () (const value_type &x, const effector_type &y) const {
return y;
}
};
};
int main() {
int N;
scanf("%d", &N);
std::vector<long long> A(N);
for (long long &x: A) {
scanf("%lld", &x);
}
segment_tree<monoid> seg(A);
long long ans = 0;
for (int i: range(0, N)) {
if (seg.fold(0, i + 1) != 1) {
continue;
}
if (A[i] == 1) {
ans += i + 1;
continue;
}
int ok = i, ng = 0;
while (ok - ng > 1) {
int md = (ok + ng) >> 1;
(seg.fold(md, i + 1) == 1 ? ng : ok) = md;
}
ans += ok;
}
printf("%lld\n", ans);
return 0;
}
KoD