結果
問題 | No.879 Range Mod 2 Query |
ユーザー |
![]() |
提出日時 | 2019-09-06 21:46:50 |
言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 289 ms / 3,000 ms |
コード長 | 12,720 bytes |
コンパイル時間 | 769 ms |
コンパイル使用メモリ | 78,128 KB |
実行使用メモリ | 13,568 KB |
最終ジャッジ日時 | 2024-06-24 22:06:33 |
合計ジャッジ時間 | 4,777 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge5 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 1 |
other | AC * 21 |
ソースコード
//#define NDEBUG#include <cstddef>#include <cstdint>#include <iostream>#include <vector>namespace n91 {using i8 = std::int_fast8_t;using i32 = std::int_fast32_t;using i64 = std::int_fast64_t;using u8 = std::uint_fast8_t;using u32 = std::uint_fast32_t;using u64 = std::uint_fast64_t;using isize = std::ptrdiff_t;using usize = std::size_t;constexpr usize operator"" _z(unsigned long long x) noexcept {return static_cast<usize>(x);}class rep {const usize f, l;public:class itr {friend rep;usize i;constexpr itr(const usize x) noexcept : i(x) {}public:void operator++() noexcept { ++i; }constexpr usize operator*() const noexcept { return i; }constexpr bool operator!=(const itr x) const noexcept { return i != x.i; }};constexpr rep(const usize first, const usize last) noexcept: f(first), l(last) {}constexpr itr begin() const noexcept { return itr(f); }constexpr itr end() const noexcept { return itr(l); }};class revrep {const usize f, l;public:class itr {friend revrep;usize i;constexpr itr(usize x) noexcept : i(x) {}public:void operator++() noexcept { --i; }constexpr usize operator*() const noexcept { return i; }constexpr bool operator!=(const itr x) const noexcept { return i != x.i; }};constexpr revrep(usize first, usize last) noexcept : f(--first), l(--last) {}constexpr itr begin() const noexcept { return itr(l); }constexpr itr end() const noexcept { return itr(f); }};template <class T> using vec_alias = std::vector<T>;template <class T> auto md_vec(const usize n, const T& value) {return std::vector<T>(n, value);}template <class... Args> auto md_vec(const usize n, Args... args) {return std::vector<decltype(md_vec(args...))>(n, md_vec(args...));}template <class T> constexpr T difference(const T& a, const T& b) {return a < b ? b - a : a - b;}template <class T> T scan() {T ret;std::cin >> ret;return ret;}} // namespace n91#include <cassert>#include <iterator>#include <utility>#include <vector>template <class Monoid> class segment_tree {public:using value_structure = Monoid;using value_type = typename value_structure::value_type;using container_type = std::vector<value_type>;using const_reference = typename container_type::const_reference;using size_type = typename container_type::size_type;protected:static size_type getsize(const size_type size) {size_type ret = 1;while (ret < size)ret <<= 1;return ret;}size_type size_;container_type tree;size_type base_size() const { return tree.size() >> 1; }void recalc(const size_type index) {tree[index] =value_structure::operation(tree[index << 1], tree[index << 1 | 1]);}public:segment_tree() : size_(0), tree() {}explicit segment_tree(const size_type size): size_(size), tree(getsize(size) << 1, value_structure::identity()) {}template <class InputIterator>segment_tree(InputIterator first, InputIterator last): size_(::std::distance(first, last)), tree() {const size_type cap = getsize(size_);tree.reserve(cap << 1);tree.resize(cap, value_structure::identity());tree.insert(tree.end(), first, last);tree.resize(cap << 1, value_structure::identity());for (size_type i = cap - 1; i; --i)recalc(i);}bool empty() const { return !size_; }size_type size() const { return size_; }const_reference operator[](const size_type index) const {assert(index < size());return tree[index + base_size()];}value_type fold(size_type first, size_type last) const {assert(first <= last);assert(first <= size());assert(last <= size());value_type ret_l = value_structure::identity(),ret_r = value_structure::identity();for (first += base_size(), last += base_size(); first < last;first >>= 1, last >>= 1) {if (first & 1)ret_l = value_structure::operation(::std::move(ret_l), tree[first++]);if (last & 1)ret_r = value_structure::operation(tree[last - 1], ::std::move(ret_r));}return value_structure::operation(::std::move(ret_l), ::std::move(ret_r));}template <class F> size_type search(const F& f) const {if (f(value_structure::identity()))return 0;if (!f(tree[1]))return size() + 1;value_type acc = value_structure::identity();size_type i = 1;while (i < base_size())if (!f(value_structure::operation(acc, tree[i <<= 1])))acc = value_structure::operation(::std::move(acc), tree[i++]);return i - base_size() + 1;}template <class F> void update(size_type index, const F& f) {assert(index < size());index += base_size();tree[index] = f(::std::move(tree[index]));while (index >>= 1)recalc(index);}};#include <cassert>#include <iterator>#include <stdexcept>#include <utility>template <class ValueMonoid, class OperatorMonoid, class Modifier,template <class> class Container>class lazy_segment_tree {public:using value_structure = ValueMonoid;using value_type = typename value_structure::value_type;using const_reference = const value_type &;using operator_structure = OperatorMonoid;using operator_type = typename operator_structure::value_type;using modifier = Modifier;using container_type = Container<::std::pair<value_type, operator_type>>;using size_type = typename container_type::size_type;private:size_type size_, height;container_type tree;static size_type getheight(const size_type size) noexcept {size_type ret = 0;while (static_cast<size_type>(1) << ret < size)++ret;return ret;}static value_type reflect(typename container_type::const_reference element) {return modifier::operation(element.first, element.second);}void recalc(const size_type index) {tree[index].first = value_structure::operation(reflect(tree[index << 1]), reflect(tree[index << 1 | 1]));}static void assign(operator_type& element, const operator_type& data) {element = operator_structure::operation(element, data);}void push(const size_type index) {assign(tree[index << 1].second, tree[index].second);assign(tree[index << 1 | 1].second, tree[index].second);tree[index].second = operator_structure::identity();}void propagate(const size_type index) {for (size_type i = height; i; --i)push(index >> i);}void thrust(const size_type index) {tree[index].first = reflect(tree[index]);push(index);}void evaluate(const size_type index) {for (size_type i = height; i; --i)thrust(index >> i);}void build(size_type index) {while (index >>= 1)recalc(index);}size_type base_size() const { return static_cast<size_type>(1) << height; }public:lazy_segment_tree() : size_(0), height(0), tree() {}explicit lazy_segment_tree(const size_type size): size_(size), height(getheight(size_)),tree(static_cast<size_type>(1) << (height + 1),{ value_structure::identity(), operator_structure::identity() }) {}template <class InputIterator>explicit lazy_segment_tree(InputIterator first, InputIterator last): size_(::std::distance(first, last)), height(getheight(size_)), tree() {const size_type cap = static_cast<size_type>(1) << height;tree.reserve(cap << 1);tree.resize(cap,{ value_structure::identity(), operator_structure::identity() });for (; first != last; ++first)tree.emplace_back(*first, operator_structure::identity());tree.resize(cap << 1,{ value_structure::identity(), operator_structure::identity() });for (size_type i = cap - 1; i; --i)recalc(i);}bool empty() const { return !size_; }size_type size() const { return size_; }const_reference operator[](size_type index) {assert(index < size());index += base_size();evaluate(index);tree[index].first = reflect(tree[index]);tree[index].second = operator_structure::identity();return tree[index].first;}const_reference at(size_type index) {if (index < size()) {throw ::std::out_of_range("index out of range");}else {index += base_size();evaluate(index);tree[index].first = reflect(tree[index]);tree[index].second = operator_structure::identity();return tree[index].first;}}value_type fold(size_type first, size_type last) {assert(first <= last);assert(first <= size());assert(last <= size());first += base_size();last += base_size();evaluate(first);evaluate(last - 1);value_type ret_l = value_structure::identity(),ret_r = value_structure::identity();for (; first < last; first >>= 1, last >>= 1) {if (first & 1)ret_l = value_structure::operation(ret_l, reflect(tree[first++]));if (last & 1)ret_r = value_structure::operation(reflect(tree[last - 1]), ret_r);}return value_structure::operation(ret_l, ret_r);}template <class F> size_type search(const F& f) {if (f(value_structure::identity()))return static_cast<size_type>(0);if (!f(reflect(tree[1])))return size() + 1;value_type acc = value_structure::identity();size_type i = 1;while (i < base_size()) {thrust(i);if (!f(value_structure::operation(acc, reflect(tree[i <<= 1]))))acc = value_structure::operation(acc, reflect(tree[i++]));}return i - base_size() + 1;}template <class F> void update(size_type index, const F& f) {assert(index < size());index += base_size();propagate(index);tree[index].first = f(reflect(tree[index]));tree[index].second = operator_structure::identity();build(index);}void update(size_type first, size_type last, const operator_type& data) {assert(first <= last);assert(first <= size());assert(last <= size());first += base_size();last += base_size();propagate(first);propagate(last - 1);for (size_type left = first, right = last; left < right;left >>= 1, right >>= 1) {if (left & 1)assign(tree[left++].second, data);if (right & 1)assign(tree[right - 1].second, data);}build(first);build(last - 1);}};template <class T> using vec_alias = std::vector<T>;#include <algorithm>#include <iostream>#include <utility>namespace n91 {struct ushi {u64 sum;u64 eve, odd;};struct beet {bool flip;bool comp;u64 add;};struct uop {using value_type = ushi;static ushi operation(const ushi& l, const ushi& r) {return ushi({ l.sum + r.sum, l.eve + r.eve, l.odd + r.odd });}static ushi identity() { return ushi({ 0, 0, 0 }); }};struct bop {using value_type = beet;static beet operation(beet l, const beet& r) {if (r.comp) {l.comp = true;if (l.add % 2 == 1) {l.flip = !l.flip;}if (r.flip) {l.flip = !l.flip;}l.add = r.add;}else {l.add += r.add;}return l;}static beet identity() { return beet({ false, false, 0 }); }};struct op {static ushi operation(ushi u, const beet& b) {if (b.comp) {if (b.flip) {std::swap(u.odd, u.eve);}u.sum = u.eve;}u.sum += b.add * (u.eve + u.odd);if (b.add % 2 == 1) {std::swap(u.odd, u.eve);}return u;}};void main_() {const usize n = scan<usize>();const usize q = scan<usize>();lazy_segment_tree<uop, bop, op, vec_alias> lsg(n);for (const auto i : rep(0_z, n)) {const u64 a = scan<u64>();lsg.update(i, [a](auto) { return ushi({ a, a % 2, (a + 1) % 2 }); });}for (const auto i : rep(0_z, q)) {u32 t;std::cin >> t;if (t == 1) {const usize l = scan<usize>() - 1;const usize r = scan<usize>();lsg.update(l, r, beet({ false, true, 0 }));}else if (t == 2) {const usize l = scan<usize>() - 1;const usize r = scan<usize>();const u64 x = scan<u64>();lsg.update(l, r, beet({ false, false, x }));}else {const usize l = scan<usize>() - 1;const usize r = scan<usize>();std::cout << lsg.fold(l, r).sum << std::endl;}}}} // namespace n91int main() {n91::main_();return 0;}