| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 
 | #include <bits/stdc++.h>using namespace std;
 
 #define int unsigned long long
 #define Mid ((L+R) >> 1)
 #define ls (u<<1)
 #define rs (u<<1|1)
 const int N = 1e6+10;
 
 int tag[N<<2];
 int a[N];
 
 struct node {
 int f, g, h;
 void set(int a) {
 h = 0;
 g = ~a;
 f = a;
 }
 } dat[N<<2];
 
 node operator+(const node& l, const node& r) {
 return {l.f & r.f, (l.f ^ r.f) & (l.g ^ r.g), l.h | r.h | (l.g & r.g)};
 }
 
 void pushup(int u) {
 dat[u] = dat[ls] + dat[rs];
 }
 
 void spread(int u, int k, int L, int R) {
 tag[u] &= k;
 dat[u].f &= k;
 if (L == R) {
 
 assert(dat[u].h == 0);
 dat[u].g |= ~k;
 }
 else {
 
 dat[u].h |= ~k;
 dat[u].g &= k;
 }
 }
 
 void pushdown(int u, int L, int R) {
 spread(ls, tag[u], L, Mid);
 spread(rs, tag[u], Mid+1, R);
 tag[u] = -1;
 }
 
 void build(int u, int L, int R) {
 tag[u] = -1;
 if (L == R) return dat[u].set(a[L]), void();
 build(ls, L, Mid);
 build(rs, Mid+1, R);
 pushup(u);
 }
 
 void modify(int u, int l, int r, int k, int L, int R) {
 if (l <= L && R <= r) return spread(u, k, L, R);
 pushdown(u, L, R);
 if (l <= Mid) modify(ls, l, r, k, L, Mid);
 if (Mid+1 <= r) modify(rs, l, r, k, Mid+1, R);
 pushup(u);
 }
 
 void modify(int u, int p, int k, int L, int R) {
 if (L == R) return dat[u].set(k), void();
 pushdown(u, L, R);
 if (p <= Mid) modify(ls, p, k, L, Mid);
 else modify(rs, p, k, Mid+1, R);
 pushup(u);
 }
 
 node query(int u, int l, int r, int L, int R) {
 if (l > r) return {-1ull, -1ull, -1ull};
 if (l <= L && R <= r) return dat[u];
 pushdown(u, L, R);
 if (l > Mid) return query(rs, l, r, Mid+1, R);
 else if (r < Mid+1) return query(ls, l, r, L, Mid);
 else return query(ls, l, r, L, Mid) + query(rs, l, r, Mid+1, R);
 }
 
 int querypos(int u, int l, int r, int k, int L, int R) {
 if (l <= L && R <= r && (dat[u].g & k) == 0) return 0;
 if (L == R) return L;
 pushdown(u, L, R);
 int res = 0;
 if (l <= Mid) res += querypos(ls, l, r, k, L, Mid);
 if (Mid+1 <= r) res += querypos(rs, l, r, k, Mid+1, R);
 return res;
 }
 
 signed main() {
 ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
 int n, q;
 cin >> n >> q;
 for (int i = 1; i <= n; i++) cin >> a[i];
 build(1, 1, n);
 while (q--) {
 int op, l, r, x, s;
 cin >> op;
 if (op == 1) {
 cin >> l >> r >> x;
 modify(1, l, r, x, 1, n);
 }
 else if (op == 2) {
 cin >> s >> x;
 modify(1, s, x, 1, n);
 }
 else {
 cin >> l >> r;
 node nd = query(1, l, r, 1, n);
 int g = nd.g;
 if (g == 0) cout << nd.f << '\n';
 else {
 int k = 1ull << (63 - __builtin_clzll(nd.g));
 int pos = querypos(1, l, r, k, 1, n);
 cout << (query(1, l, pos-1, 1, n).f & query(1, pos+1, r, 1, n).f) << '\n';
 }
 }
 }
 return 0;
 }
 
 |