結果
問題 | No.1099 Range Square Sum |
ユーザー | KoD |
提出日時 | 2020-06-26 22:08:18 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 309 ms / 2,000 ms |
コード長 | 5,978 bytes |
コンパイル時間 | 856 ms |
コンパイル使用メモリ | 86,472 KB |
実行使用メモリ | 18,708 KB |
最終ジャッジ日時 | 2024-07-04 21:21:34 |
合計ジャッジ時間 | 5,563 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge2 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 1 ms
6,816 KB |
testcase_01 | AC | 2 ms
6,944 KB |
testcase_02 | AC | 2 ms
6,940 KB |
testcase_03 | AC | 2 ms
6,944 KB |
testcase_04 | AC | 2 ms
6,940 KB |
testcase_05 | AC | 2 ms
6,940 KB |
testcase_06 | AC | 2 ms
6,940 KB |
testcase_07 | AC | 2 ms
6,940 KB |
testcase_08 | AC | 1 ms
6,940 KB |
testcase_09 | AC | 2 ms
6,940 KB |
testcase_10 | AC | 2 ms
6,944 KB |
testcase_11 | AC | 4 ms
6,944 KB |
testcase_12 | AC | 4 ms
6,940 KB |
testcase_13 | AC | 4 ms
6,940 KB |
testcase_14 | AC | 4 ms
6,940 KB |
testcase_15 | AC | 4 ms
6,944 KB |
testcase_16 | AC | 3 ms
6,944 KB |
testcase_17 | AC | 4 ms
6,944 KB |
testcase_18 | AC | 4 ms
6,940 KB |
testcase_19 | AC | 4 ms
6,940 KB |
testcase_20 | AC | 4 ms
6,944 KB |
testcase_21 | AC | 305 ms
18,620 KB |
testcase_22 | AC | 308 ms
18,612 KB |
testcase_23 | AC | 309 ms
18,588 KB |
testcase_24 | AC | 308 ms
18,708 KB |
testcase_25 | AC | 309 ms
18,608 KB |
testcase_26 | AC | 263 ms
18,632 KB |
testcase_27 | AC | 263 ms
18,632 KB |
testcase_28 | AC | 264 ms
18,600 KB |
testcase_29 | AC | 265 ms
18,604 KB |
testcase_30 | AC | 263 ms
18,620 KB |
ソースコード
#include <iostream> #include <algorithm> #include <utility> #include <numeric> #include <vector> #include <array> 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; } struct range { using itr = int64_t; struct iterator { itr i; constexpr iterator(itr i_) noexcept : i(i_) { } constexpr void operator ++ () noexcept { ++i; } constexpr itr operator * () const noexcept { return i; } constexpr bool operator != (iterator x) const noexcept { return i != x.i; } }; const iterator l, r; constexpr range(itr l_, itr r_) noexcept : l(l_), r(std::max(l_, r_)) { } constexpr iterator begin() const noexcept { return l; } constexpr iterator end() const noexcept { return r; } }; struct revrange { using itr = int64_t; struct iterator { itr i; constexpr iterator(itr i_) noexcept : i(i_) { } constexpr void operator ++ () noexcept { --i; } constexpr itr operator * () const noexcept { return i; } constexpr bool operator != (iterator x) const noexcept { return i != x.i; } }; const iterator l, r; constexpr revrange(itr l_, itr r_) noexcept : l(l_ - 1), r(std::max(l_, r_) - 1) { } constexpr iterator begin() const noexcept { return r; } constexpr iterator end() const noexcept { return l; } }; using i32 = int32_t; using i64 = int64_t; using u32 = uint32_t; using u64 = uint64_t; constexpr i32 inf32 = (i32(1) << 30) - 1; constexpr i64 inf64 = (i64(1) << 62) - 1; template <class T> class lazy_propagation_segment_tree { public: using value_type = typename T::value_type; using effector_type = typename T::effector_type; static inline const auto op1 = typename T::value_operation(); static inline const auto op2 = typename T::effector_operation(); static inline const auto op3 = typename T::merge_operation(); private: int size, height; std::vector<value_type> node; std::vector<effector_type> lazy; value_type fetch(int i, int l) const { if (lazy[i] == op2.identity) return node[i]; return op3(node[i], lazy[i], l); } void apply(int i, int l) { if (lazy[i] == op2.identity) return; if (i < size) { lazy[i << 1 | 0] = op2(lazy[i << 1 | 0], lazy[i]); lazy[i << 1 | 1] = op2(lazy[i << 1 | 1], lazy[i]); } node[i] = op3(node[i], lazy[i], l); lazy[i] = op2.identity; } void update() { for (int i = size - 1; i > 0; --i) { node[i] = op1(node[i << 1 | 0], node[i << 1 | 1]); } } void flush(int i) { for (int k = height; k >= 0; --k) { apply(i >> k, 1 << k); } } void lift(int i) { i >>= 1; int l = 1; while (i > 0) { node[i] = op1(fetch(i << 1 | 0, l), fetch(i << 1 | 1, l)); i >>= 1; l <<= 1; } } public: lazy_propagation_segment_tree() = default; lazy_propagation_segment_tree(int size_, const value_type &initial_ = op1.identity) { init(size_, initial_); } lazy_propagation_segment_tree(const std::vector<value_type> &node_) { build(node_); } void init(int size_, const value_type &initial_ = op1.identity) { size = 1; height = 0; while (size < size_) { size <<= 1; ++height; } node.assign(size << 1, initial_); lazy.assign(size << 1, op2.identity); update(); } void build(const std::vector<value_type> &node_) { init(node_.size()); for (int i = 0; i < node_.size(); ++i) { node[i + size] = node_[i]; } update(); } void assign(int i, const value_type &x) { i += size; flush(i); node[i] = x; lift(i); } void modify(int l, int r, const effector_type &x) { if (l >= r) return; flush(l + size); flush(r + size - 1); int tl = l + size, tr = r + size, k = 1; while (tl < tr) { if (tl & 1) { lazy[tl] = op2(lazy[tl], x); apply(tl, k); ++tl; } if (tr & 1) { --tr; lazy[tr] = op2(lazy[tr], x); apply(tr, k); } tl >>= 1; tr >>= 1; k <<= 1; } lift(l + size); lift(r + size - 1); } value_type fold(int l, int r) { if (l >= r) return op1.identity; flush(l + size); flush(r + size - 1); int tl = l + size, tr = r + size, k = 1; value_type resl = op1.identity, resr = op1.identity; while (tl < tr) { if (tl & 1) { apply(tl, k); resl = op1(resl, node[tl]); ++tl; } if (tr & 1) { --tr; apply(tr, k); resr = op1(node[tr], resr); } tl >>= 1; tr >>= 1; k <<= 1; } return op1(resl, resr); } }; struct monoid { using value_type = std::pair<i64, i64>; using effector_type = i64; struct value_operation { value_type identity = std::make_pair(0, 0); value_type operator () (const value_type &x, const value_type &y) const { return { x.first + y.first, x.second + y.second }; } }; struct effector_operation { effector_type identity = 0; effector_type operator () (const effector_type &x, const effector_type &y) const { return x + y; } }; struct merge_operation { value_type operator () (const value_type &x, const effector_type &y, size_t l = 1) const { return { x.first + 2 * x.second * y + y * y * l, x.second + y * l }; } }; }; int main() { size_t N; std::cin >> N; std::vector<std::pair<i64, i64>> build(N); for (auto i: range(0, N)) { std::cin >> build[i].second; build[i].first = build[i].second * build[i].second; } lazy_propagation_segment_tree<monoid> seg(build); size_t Q; std::cin >> Q; while (Q--) { i32 t, l, r; std::cin >> t >> l >> r; --l; if (t == 1) { i32 x; std::cin >> x; seg.modify(l, r, x); } else { std::cout << seg.fold(l, r).first << '\n'; } } return 0; }