Untitled
unknown
c_cpp
a year ago
3.8 kB
12
Indexable
#include <bits/stdc++.h> using namespace std; #define ll long long int tt, tc; const int N = 1e5 + 9; const int LOG = 20; struct xor_basis { int basis[LOG]; xor_basis() { for (int i = 0; i < LOG; i++) basis[i] = 0; } void insert(int mask) { for (int i = LOG - 1; i >= 0; --i) if (mask & (1 << i)) { if (!basis[i]) { basis[i] = mask; return; } mask ^= basis[i]; } } void modify_and(int x) { for (int j = LOG - 1; j >= 0; --j) { basis[j] &= x; } vector<int> elements; for (int i = 0; i < LOG; i++) if (basis[i] > 0) elements.push_back(basis[i]); for (int i = 0; i < LOG; i++) if (basis[i] > 0) basis[i] = 0; for (int element : elements) insert(element); } int find_max() { int ans = 0; for (int i = LOG - 1; i >= 0; --i) if (basis[i] > 0 && (ans & (1 << i)) == 0) ans ^= basis[i]; return ans; } }; struct node { xor_basis basis; int oring; node() { oring = 0; } node(int x) { oring = x; basis.insert(x); } }; node neg; node merge(node a, node b) { if (a.oring == -1) return b; if (b.oring == -1) return a; node res; res.oring = a.oring | b.oring; res.basis = a.basis; for (int i = 0; i < LOG; ++i) if (b.basis.basis[i]) res.basis.insert(b.basis.basis[i]); return res; } int n; int a[N]; node tree[N << 2]; int lazy[N << 2]; void push(int p, int l, int r) { if (lazy[p] == (1 << 20) - 1) return; tree[p].basis.modify_and(lazy[p]); if (l != r) { lazy[p << 1] = lazy[p << 1] & lazy[p]; lazy[p << 1 | 1] = lazy[p << 1 | 1] & lazy[p]; } lazy[p] = (1 << 20) - 1; } void build(int p = 1, int l = 1, int r = n) { lazy[p] = (1 << 20) - 1; if (l == r) { tree[p] = node(a[l]); return; } int m = (l + r) >> 1; build(p << 1, l, m); build(p << 1 | 1, m + 1, r); tree[p] = merge(tree[p << 1], tree[p << 1 | 1]); } void modify(int i, int x, int p = 1, int l = 1, int r = n) { push(p, l, r); if (l == r) { a[i] = x; tree[p] = node(x); return; } int m = (l + r) >> 1; if (i <= m) modify(i, x, p << 1, l, m); else modify(i, x, p << 1 | 1, m + 1, r); tree[p] = merge(tree[p << 1], tree[p << 1 | 1]); } void update(int L, int R, int x, int p = 1, int l = 1, int r = n) { push(p, l, r); if (L > r || l > R) return; if (L <= l && r <= R) { lazy[p] = lazy[p] & x; push(p, l, r); return; } int m = (l + r) >> 1; update(L, R, x, p << 1, l, m); update(L, R, x, p << 1 | 1, m + 1, r); tree[p] = merge(tree[p << 1], tree[p << 1 | 1]); } node query(int L, int R, int p = 1, int l = 1, int r = n) { push(p, l, r); if (L > r || l > R) return neg; if (L <= l && r <= R) return tree[p]; int m = (l + r) >> 1; return merge(query(L, R, p << 1, l, m), query(L, R, p << 1 | 1, m + 1, r)); } void solve() { int q; cin >> n >> q; for (int i = 1; i <= n; i++) cin >> a[i]; build(); while (q--) { int type; cin >> type; if (type == 1) { int l, r, x; cin >> l >> r >> x; update(l, r, x); } else if (type == 2) { int i, x; cin >> i >> x; modify(i, x); } else { int l, r; cin >> l >> r; cout << query(l, r).basis.find_max() << '\n'; } } } int main() { neg.oring = -1; ios::sync_with_stdio(0); cin.tie(0); tt = 1, tc = 1; cin >> tt; while (tt--) solve(), tc++; }
Editor is loading...
Leave a Comment