Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- // tiom4eg's precompiler options
- // POGGERS POGGERS POGGERS POGGERS POGGERS POGGERS POGGERS
- // IO settings
- #define fastIO ios_base::sync_with_stdio(false); cin.tie(0)
- // Quick types
- #define ll long long
- #define ld long double
- //#define ull unsigned long long
- #define pii pair <int, int>
- #define vi vector <int>
- #define mi vector <vector <int>>
- // Quick functions
- #define endl "\n"
- #define F first
- #define S second
- #define all(a) a.begin(), a.end()
- #define sz(a) (int)(a.size())
- #define pb push_back
- #define mp make_pair
- // Quick fors
- #define FOR(i, a, b) for (int i = a; i < b; ++i)
- #define FORS(i, a, b, c) for (int i = a; i < b; i += c)
- #define RFOR(i, a, b) for (int i = a; i >= b; --i)
- #define EACH(e, a) for (auto& e : a)
- // Pragmas
- #ifndef TIOM4EG
- #pragma GCC optimize("O3") // let the chaos begin!
- #pragma GCC target("avx,avx2,tune=native")
- #pragma GCC comment(linker, "/stack:200000000")
- #endif
- // PBDS
- #include <ext/pb_ds/assoc_container.hpp>
- #include <ext/pb_ds/tree_policy.hpp>
- #define pbds tree <int, null_type, less <int>, rb_tree_tag, tree_order_statistics_node_update>
- using namespace __gnu_pbds;
- // POGGERS POGGERS POGGERS POGGERS POGGERS POGGERS POGGERS
- using namespace std;
- mt19937 rng(chrono::duration_cast<chrono::milliseconds>(chrono::system_clock::now().time_since_epoch()).count());
- constexpr int INF = 1e9 + 7, MD = 998244353, MAX = 200007, LG = 20, R = 1 << LG, MOD = 1000000007, MOD2 = 1e9 + 9, B = 256;
- const ll INFLL = 1e18 + 7;
- struct IOPre {
- static constexpr int TEN = 10, SZ = TEN * TEN * TEN * TEN;
- std::array<char, 4 * SZ> num;
- constexpr IOPre() : num{} {
- for (int i = 0; i < SZ; i++) {
- int n = i;
- for (int j = 3; j >= 0; j--) {
- num[i * 4 + j] = static_cast<char>(n % TEN + '0');
- n /= TEN;
- }
- }
- }
- };
- struct IO {
- #if !HAVE_DECL_FREAD_UNLOCKED
- #define fread_unlocked fread
- #endif
- #if !HAVE_DECL_FWRITE_UNLOCKED
- #define fwrite_unlocked fwrite
- #endif
- static constexpr int SZ = 1 << 22, LEN = 32, TEN = 10, HUNDRED = TEN * TEN,
- THOUSAND = HUNDRED * TEN, TENTHOUSAND = THOUSAND * TEN,
- MAGIC_MULTIPLY = 205, MAGIC_SHIFT = 11, MASK = 15,
- TWELVE = 12, SIXTEEN = 16;
- static constexpr IOPre io_pre = {};
- std::array<char, SZ> input_buffer, output_buffer;
- int input_ptr_left, input_ptr_right, output_ptr_right;
- IO()
- : input_buffer{},
- output_buffer{},
- input_ptr_left{},
- input_ptr_right{},
- output_ptr_right{} {}
- IO(const IO&) = delete;
- IO(IO&&) = delete;
- IO& operator=(const IO&) = delete;
- IO& operator=(IO&&) = delete;
- ~IO() {
- flush();
- }
- template <class T>
- struct is_char {
- static constexpr bool value = std::is_same_v<T, char>;
- };
- template <class T>
- struct is_bool {
- static constexpr bool value = std::is_same_v<T, bool>;
- };
- template <class T>
- struct is_string {
- static constexpr bool value =
- std::is_same_v<T, std::string> || std::is_same_v<T, const char*> ||
- std::is_same_v<T, char*> || std::is_same_v<std::decay_t<T>, char*>;
- };
- template <class T, class D = void>
- struct is_custom {
- static constexpr bool value = false;
- };
- template <class T>
- struct is_custom<T, std::void_t<typename T::internal_value_type>> {
- static constexpr bool value = true;
- };
- template <class T>
- struct is_default {
- static constexpr bool value = is_char<T>::value || is_bool<T>::value ||
- is_string<T>::value ||
- std::is_integral_v<T>;
- };
- template <class T, class D = void>
- struct is_iterable {
- static constexpr bool value = false;
- };
- template <class T>
- struct is_iterable<
- T, typename std::void_t<decltype(std::begin(std::declval<T>()))>> {
- static constexpr bool value = true;
- };
- template <class T, class D = void, class E = void>
- struct is_applyable {
- static constexpr bool value = false;
- };
- template <class T>
- struct is_applyable<T, std::void_t<typename std::tuple_size<T>::type>,
- std::void_t<decltype(std::get<0>(std::declval<T>()))>> {
- static constexpr bool value = true;
- };
- template <class T>
- static constexpr bool needs_newline = (is_iterable<T>::value ||
- is_applyable<T>::value) &&
- (!is_default<T>::value);
- template <typename T, typename U>
- struct any_needs_newline {
- static constexpr bool value = false;
- };
- template <typename T>
- struct any_needs_newline<T, std::index_sequence<>> {
- static constexpr bool value = false;
- };
- template <typename T, std::size_t I, std::size_t... Is>
- struct any_needs_newline<T, std::index_sequence<I, Is...>> {
- static constexpr bool value =
- needs_newline<decltype(std::get<I>(std::declval<T>()))> ||
- any_needs_newline<T, std::index_sequence<Is...>>::value;
- };
- inline void load() {
- memmove(std::begin(input_buffer),
- std::begin(input_buffer) + input_ptr_left,
- input_ptr_right - input_ptr_left);
- input_ptr_right =
- input_ptr_right - input_ptr_left +
- static_cast<int>(fread_unlocked(
- std::begin(input_buffer) + input_ptr_right - input_ptr_left, 1,
- SZ - input_ptr_right + input_ptr_left, stdin));
- input_ptr_left = 0;
- }
- inline void read_char(char& c) {
- if (input_ptr_left + LEN > input_ptr_right) load();
- c = input_buffer[input_ptr_left++];
- }
- inline void read_string(std::string& x) {
- char c;
- while (read_char(c), c < '!') continue;
- x = c;
- while (read_char(c), c >= '!') x += c;
- }
- template <class T>
- inline std::enable_if_t<std::is_integral_v<T>, void> read_int(T& x) {
- if (input_ptr_left + LEN > input_ptr_right) load();
- char c = 0;
- do c = input_buffer[input_ptr_left++];
- while (c < '-');
- [[maybe_unused]] bool minus = false;
- if constexpr (std::is_signed<T>::value == true)
- if (c == '-') minus = true, c = input_buffer[input_ptr_left++];
- x = 0;
- while (c >= '0')
- x = x * TEN + (c & MASK), c = input_buffer[input_ptr_left++];
- if constexpr (std::is_signed<T>::value == true)
- if (minus) x = -x;
- }
- inline void skip_space() {
- if (input_ptr_left + LEN > input_ptr_right) load();
- while (input_buffer[input_ptr_left] <= ' ') input_ptr_left++;
- }
- inline void flush() {
- fwrite_unlocked(std::begin(output_buffer), 1, output_ptr_right, stdout);
- output_ptr_right = 0;
- }
- inline void write_char(char c) {
- if (output_ptr_right > SZ - LEN) flush();
- output_buffer[output_ptr_right++] = c;
- }
- inline void write_bool(bool b) {
- if (output_ptr_right > SZ - LEN) flush();
- output_buffer[output_ptr_right++] = b ? '1' : '0';
- }
- inline void write_string(const std::string& s) {
- for (auto x : s) write_char(x);
- }
- inline void write_string(const char* s) {
- while (*s) write_char(*s++);
- }
- inline void write_string(char* s) {
- while (*s) write_char(*s++);
- }
- template <typename T>
- inline std::enable_if_t<std::is_integral_v<T>, void> write_int(T x) {
- if (output_ptr_right > SZ - LEN) flush();
- if (!x) {
- output_buffer[output_ptr_right++] = '0';
- return;
- }
- if constexpr (std::is_signed<T>::value == true)
- if (x < 0) output_buffer[output_ptr_right++] = '-', x = -x;
- int i = TWELVE;
- std::array<char, SIXTEEN> buf{};
- while (x >= TENTHOUSAND) {
- memcpy(std::begin(buf) + i,
- std::begin(io_pre.num) + (x % TENTHOUSAND) * 4, 4);
- x /= TENTHOUSAND;
- i -= 4;
- }
- if (x < HUNDRED) {
- if (x < TEN) {
- output_buffer[output_ptr_right++] = static_cast<char>('0' + x);
- } else {
- std::uint32_t q =
- (static_cast<std::uint32_t>(x) * MAGIC_MULTIPLY) >>
- MAGIC_SHIFT;
- std::uint32_t r = static_cast<std::uint32_t>(x) - q * TEN;
- output_buffer[output_ptr_right] = static_cast<char>('0' + q);
- output_buffer[output_ptr_right + 1] =
- static_cast<char>('0' + r);
- output_ptr_right += 2;
- }
- } else {
- if (x < THOUSAND) {
- memcpy(std::begin(output_buffer) + output_ptr_right,
- std::begin(io_pre.num) + (x << 2) + 1, 3),
- output_ptr_right += 3;
- } else {
- memcpy(std::begin(output_buffer) + output_ptr_right,
- std::begin(io_pre.num) + (x << 2), 4),
- output_ptr_right += 4;
- }
- }
- memcpy(std::begin(output_buffer) + output_ptr_right,
- std::begin(buf) + i + 4, TWELVE - i);
- output_ptr_right += TWELVE - i;
- }
- template <typename T_>
- IO& operator<<(T_&& x) {
- using T = typename std::remove_cv<
- typename std::remove_reference<T_>::type>::type;
- static_assert(is_custom<T>::value or is_default<T>::value or
- is_iterable<T>::value or is_applyable<T>::value);
- if constexpr (is_custom<T>::value) {
- write_int(x.get());
- } else if constexpr (is_default<T>::value) {
- if constexpr (is_bool<T>::value) {
- write_bool(x);
- } else if constexpr (is_string<T>::value) {
- write_string(x);
- } else if constexpr (is_char<T>::value) {
- write_char(x);
- } else if constexpr (std::is_integral_v<T>) {
- write_int(x);
- }
- } else if constexpr (is_iterable<T>::value) {
- // strings are immune
- using E = decltype(*std::begin(x));
- constexpr char sep = needs_newline<E> ? '\n' : ' ';
- int i = 0;
- for (const auto& y : x) {
- if (i++) write_char(sep);
- operator<<(y);
- }
- } else if constexpr (is_applyable<T>::value) {
- // strings are immune
- constexpr char sep =
- (any_needs_newline<
- T, std::make_index_sequence<std::tuple_size_v<T>>>::value)
- ? '\n'
- : ' ';
- int i = 0;
- std::apply(
- [this, &sep, &i](auto const&... y) {
- (((i++ ? write_char(sep) : void()), this->operator<<(y)),
- ...);
- },
- x);
- }
- return *this;
- }
- template <typename T>
- IO& operator>>(T& x) {
- static_assert(is_custom<T>::value or is_default<T>::value or
- is_iterable<T>::value or is_applyable<T>::value);
- static_assert(!is_bool<T>::value);
- if constexpr (is_custom<T>::value) {
- typename T::internal_value_type y;
- read_int(y);
- x = y;
- } else if constexpr (is_default<T>::value) {
- if constexpr (is_string<T>::value) {
- read_string(x);
- } else if constexpr (is_char<T>::value) {
- read_char(x);
- } else if constexpr (std::is_integral_v<T>) {
- read_int(x);
- }
- } else if constexpr (is_iterable<T>::value) {
- for (auto& y : x) operator>>(y);
- } else if constexpr (is_applyable<T>::value) {
- std::apply([this](auto&... y) { ((this->operator>>(y)), ...); }, x);
- }
- return *this;
- }
- IO* tie(std::nullptr_t) {
- return this;
- }
- void sync_with_stdio(bool) {}
- };
- IO io;
- #define cin io
- #define cout io
- #define int long long
- int d2[LG];
- int t[2 * R][2];
- void tag(int v, int x, int l) { t[v][0] = x * l, t[v][1] = x; }
- void push(int v, int l) {
- if (~t[v][1]) {
- tag(2 * v, t[v][1], l >> 1), tag(2 * v + 1, t[v][1], l >> 1);
- t[v][1] = -1;
- }
- }
- // fuck you for making me use [l; r] instead of [l; r)
- void upd(int ql, int qr, int x, int k, int v = 1, int h = 19, int nl = 0, int nr = R - 1) {
- if (ql == nl && qr == nr) return tag(v, x, nr - nl + 1);
- push(v, nr - nl + 1);
- int nm = (nl + (nr + 1)) >> 1;
- if (qr <= nm - 1) {
- if (k & d2[h]) upd(ql ^ d2[h], qr ^ d2[h], x, k, 2 * v + 1, h - 1, nm, nr);
- else upd(ql, qr, x, k, 2 * v, h - 1, nl, nm - 1);
- }
- else if (ql >= nm) {
- if (k & d2[h]) upd(ql ^ d2[h], qr ^ d2[h], x, k, 2 * v, h - 1, nl, nm - 1);
- else upd(ql, qr, x, k, 2 * v + 1, h - 1, nm, nr);
- }
- else {
- if (k & d2[h]) upd(nl, qr ^ d2[h], x, k, 2 * v, h - 1, nl, nm - 1), upd(ql ^ d2[h], nr, x, k, 2 * v + 1, h - 1, nm, nr);
- else upd(ql, nm - 1, x, k, 2 * v, h - 1, nl, nm - 1), upd(nm, qr, x, k, 2 * v + 1, h - 1, nm, nr);
- }
- t[v][0] = t[2 * v][0] + t[2 * v + 1][0];
- }
- int get(int ql, int qr, int k, int v = 1, int h = 19, int nl = 0, int nr = R - 1) {
- if (ql == nl && qr == nr) return t[v][0];
- push(v, nr - nl + 1);
- int nm = (nl + (nr + 1)) >> 1;
- if (qr <= nm - 1) {
- if (k & d2[h]) return get(ql ^ d2[h], qr ^ d2[h], k, 2 * v + 1, h - 1, nm, nr);
- return get(ql, qr, k, 2 * v, h - 1, nl, nm - 1);
- }
- if (ql >= nm) {
- if (k & d2[h]) return get(ql ^ d2[h], qr ^ d2[h], k, 2 * v, h - 1, nl, nm - 1);
- return get(ql, qr, k, 2 * v + 1, h - 1, nm, nr);
- }
- if (k & d2[h]) return get(nl, qr ^ d2[h], k, 2 * v, h - 1, nl, nm - 1) + get(ql ^ d2[h], nr, k, 2 * v + 1, h - 1, nm, nr);
- return get(ql, nm - 1, k, 2 * v, h - 1, nl, nm - 1) + get(nm, qr, k, 2 * v + 1, h - 1, nm, nr);
- }
- signed main() {
- FOR(i, 0, LG) d2[i] = 1 << i;
- FOR(i, 1, 2 * R) t[i][1] = -1;
- fastIO;
- int n; cin >> n;
- FOR(i, 0, 1 << n) cin >> t[R + i][0];
- RFOR(i, R - 1, 1) t[i][0] = t[2 * i][0] + t[2 * i + 1][0];
- int q; cin >> q;
- while (q--) {
- int op, l, r, k; cin >> op >> l >> r >> k;
- if (op == 1) {
- int x; cin >> x;
- upd(l, r, x, k);
- }
- else cout << get(l, r, k) << endl;
- }
- }
Add Comment
Please, Sign In to add comment