1 2 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; }
|