#include #pragma GCC optimize ("O3") #pragma GCC target ("avx") using namespace std; using int64 = long long; const int mod = 1e9 + 7; const int64 infll = (1LL << 62) - 1; const int inf = (1 << 30) - 1; struct IoSetup { IoSetup() { cin.tie(nullptr); ios::sync_with_stdio(false); cout << fixed << setprecision(10); cerr << fixed << setprecision(10); } } iosetup; template< typename T1, typename T2 > ostream &operator<<(ostream &os, const pair< T1, T2 > &p) { os << p.first << " " << p.second; return os; } template< typename T1, typename T2 > istream &operator>>(istream &is, pair< T1, T2 > &p) { is >> p.first >> p.second; return is; } template< typename T > ostream &operator<<(ostream &os, const vector< T > &v) { for(int i = 0; i < (int) v.size(); i++) { os << v[i] << (i + 1 != v.size() ? " " : ""); } return os; } template< typename T > istream &operator>>(istream &is, vector< T > &v) { for(T &in : v) is >> in; return is; } template< typename T1, typename T2 > inline bool chmax(T1 &a, T2 b) { return a < b && (a = b, true); } template< typename T1, typename T2 > inline bool chmin(T1 &a, T2 b) { return a > b && (a = b, true); } template< typename T = int64 > vector< T > make_v(size_t a) { return vector< T >(a); } template< typename T, typename... Ts > auto make_v(size_t a, Ts... ts) { return vector< decltype(make_v< T >(ts...)) >(a, make_v< T >(ts...)); } template< typename T, typename V > typename enable_if< is_class< T >::value == 0 >::type fill_v(T &t, const V &v) { t = v; } template< typename T, typename V > typename enable_if< is_class< T >::value != 0 >::type fill_v(T &t, const V &v) { for(auto &e : t) fill_v(e, v); } template< typename F > struct FixPoint : F { FixPoint(F &&f) : F(forward< F >(f)) {} template< typename... Args > decltype(auto) operator()(Args &&... args) const { return F::operator()(*this, forward< Args >(args)...); } }; template< typename F > inline decltype(auto) MFP(F &&f) { return FixPoint< F >{forward< F >(f)}; } using ll = long long; struct RMQ { using type = pair< int64, int >; static type id() { return type(0, 0); } static type op(const type &l, const type &r) { return type(l.first + r.first, l.second + r.second); } }; template< typename M > class node { using T = typename M::type; public: T val; node< M > *l, *r; node(T val_) : val(val_), l(nullptr), r(nullptr) {} }; template< typename M > class dynamic_segment_tree { using T = typename M::type; const ll n; node< M > *root; T value(node< M > *t) { return t ? t->val : M::id(); } T sub(ll l, ll r, node< M > *n, ll lb, ll ub) { if(!n || ub <= l || r <= lb) return M::id(); if(l <= lb && ub <= r) return n->val; ll c = (lb + ub) / 2; return M::op(sub(l, r, n->l, lb, c), sub(l, r, n->r, c, ub)); } node< M > *suc(ll p, node< M > *t, ll lb, ll ub, T val) { if(!t) t = new node< M >(M::id()); if(lb + 1 == ub) { t->val = val; return t; } ll c = (lb + ub) / 2; if(p < c) t->l = suc(p, t->l, lb, c, val); else t->r = suc(p, t->r, c, ub, val); t->val = M::op(value(t->l), value(t->r)); return t; } public: dynamic_segment_tree(ll n_) : n(1ll << (ll) ceil(log2(n_))), root(nullptr) { } void update(ll p, T val) { root = suc(p, root, 0, n, val); } T find(ll l, ll r) { return sub(l, r + 1, root, 0, n); } }; template< typename M > class node2 { using T = typename M::type; public: dynamic_segment_tree< M > val; node2< M > *l, *r; node2(ll size) : val(size), l(nullptr), r(nullptr) {} }; template< typename M > class dynamic_segment_tree2 { using T = typename M::type; const ll h, w; node2< M > *root; T value(node2< M > *t, ll p) { return t ? t->val.find(p, p) : M::id(); } T sub(ll li, ll lj, ll ri, ll rj, node2< M > *n, ll lb, ll ub) { if(!n || ub <= li || ri <= lb) return M::id(); if(li <= lb && ub <= ri) { return n->val.find(lj, rj); } ll c = (lb + ub) / 2; return M::op(sub(li, lj, ri, rj, n->l, lb, c), sub(li, lj, ri, rj, n->r, c, ub)); } node2< M > *suc(ll pi, ll pj, node2< M > *t, ll lb, ll ub, T val) { if(!t) t = new node2< M >(w); if(lb + 1 == ub) { t->val.update(pj, val); return t; } ll c = (lb + ub) / 2; if(pi < c) t->l = suc(pi, pj, t->l, lb, c, val); else t->r = suc(pi, pj, t->r, c, ub, val); t->val.update(pj, M::op(value(t->l, pj), value(t->r, pj))); return t; } public: dynamic_segment_tree2(ll h_, ll w_) : h(1ll << (ll) ceil(log2(h_))), w(w_), root(nullptr) {} void update(ll pi, ll pj, T val) { root = suc(pi, pj, root, 0, h, val); } T find(ll li, ll lj, ll ri, ll rj) { return sub(li, lj, ri + 1, rj, root, 0, h); } }; template< class T > struct BinaryIndexedTree { vector< T > data; BinaryIndexedTree(int sz) { data.assign(++sz, 0); } T sum(int k) { T ret = 0; for(++k; k > 0; k -= k & -k) ret += data[k]; return (ret); } void add(int k, T x) { for(++k; k < data.size(); k += k & -k) data[k] += x; } }; int main() { int N, Q; cin >> N >> Q; vector< int64 > A(N); cin >> A; const int64 two16 = 65536; const int64 two40 = 1099511627776; dynamic_segment_tree2< RMQ > seg(two40, N); for(int i = 0; i < N; i++) { seg.update(A[i], i, make_pair(A[i], 1)); } BinaryIndexedTree< int64 > bit(N); for(int i = 0; i < N; i++) { bit.add(i, A[i]); } int64 s = 0; for(int i = 0; i < Q; i++) { int64 t, l, r; cin >> t >> l >> r; if(t == 1) { l ^= s % two16; r ^= s % two40; --l; seg.update(A[l], l, make_pair(0, 0)); bit.add(l, -A[l]); A[l] = r; bit.add(l, A[l]); seg.update(A[l], l, make_pair(A[l], 1)); } else { l ^= s % two16; r ^= s % two16; if(l > r) swap(l, r); --l; int md = (r - l) / 2; int64 val = 0; for(int i = 40; i >= 0; i--) { if(seg.find(val | (1LL << i), l, infll, r - 1).second > md) val |= 1LL << i; } auto ret = seg.find(val, l, infll, r - 1); int64 upcnt = ret.second; int64 upsum = ret.first; int64 lowcnt = (r - l) - upcnt; int64 lowsum = bit.sum(r - 1) - bit.sum(l - 1) - upsum; int64 sum = (upsum - upcnt * val) + (val * lowcnt - lowsum); cout << sum << endl; s ^= sum; } } }