xor or and 线段树
每一位维护一颗线段树
(-1)^1 =-2
(-2)^1=-1
#include <cstdio> #include<iostream> using namespace std; //#define int long long #define si signed #define sc(x) scanf("%d", &x); #define P pair<int, int> int lazy[4][4000005]; int sum[4][4000005]; int A[1000005]; int n, m; void pushdown(int id, int x, int l, int r) { if (lazy[id][x] == 1) { lazy[id][x] = 0; int mid = l + r >> 1; lazy[id][x << 1] ^= 1; sum[id][x << 1] = (mid - l + 1) - sum[id][x << 1]; lazy[id][x << 1 | 1] ^= 1; sum[id][x << 1 | 1] = (r - mid) - sum[id][x << 1 | 1]; } else if (lazy[id][x] == -2) { lazy[id][x] = 0; int mid = l + r >> 1; lazy[id][x << 1] = -2; sum[id][x << 1] = (mid - l + 1); lazy[id][x << 1 | 1] = -2; sum[id][x << 1 | 1] = (r - mid); } else if (lazy[id][x] == -1) { lazy[id][x] = 0; int mid = l + r >> 1; lazy[id][x << 1] = -1; sum[id][x << 1] = 0; lazy[id][x << 1 | 1] = -1; sum[id][x << 1 | 1] = 0; } } void pushup(int id, int x) { sum[id][x] = sum[id][x << 1] + sum[id][x << 1 | 1]; } void build(int id, int l, int r, int x) { lazy[id][x] = 0; if (l == r) { sum[id][x] = ((A[l] >> id) & 1); return; } int mid = (l + r) / 2; build(id, l, mid, x << 1); build(id, mid + 1, r, x << 1 | 1); pushup(id, x); } void update(int id, int l, int r, int x, int type, int L, int R) { if (type == 2) { // cout<<type<<"type"<<endl; if (l >= L && r <= R) { lazy[id][x] ^= 1; sum[id][x] = (r - l + 1) - sum[id][x]; //cout<<L<<' '<<R<<endl; return; } pushdown(id, x, l, r); int mid = (l + r) >> 1; if (L <= mid) update(id, l, mid, x << 1, type, L, R); if (R > mid) update(id, mid + 1, r, x << 1 | 1, type, L, R); pushup(id, x); } else if (type == 4) { if (l >= L && r <= R) { lazy[id][x] = -1; sum[id][x] = 0; return; } pushdown(id, x, l, r); int mid = (l + r) >> 1; if (L <= mid) update(id, l, mid, x << 1, type, L, R); if (R > mid) update(id, mid + 1, r, x << 1 | 1, type, L, R); pushup(id, x); } else { if (l >= L && r <= R) { lazy[id][x] = -2; sum[id][x] = r - l + 1; return; } pushdown(id, x, l, r); int mid = (l + r) >> 1; if (L <= mid) update(id, l, mid, x << 1, type, L, R); if (R > mid) update(id, mid + 1, r, x << 1 | 1, type, L, R); pushup(id, x); } } int query(int id, int l, int r, int x, int L, int R) { int ans = 0; if (L <= l && r <= R) { return sum[id][x]; } pushdown(id, x, l, r); int mid = l + r >> 1; if (L <= mid) ans += query(id, l, mid, x << 1, L, R); if (R > mid) ans += query(id, mid + 1, r, x << 1 | 1, L, R); return ans; } si main() { int T; sc(T) string s; while (T--) { sc(n) sc(m); for (int i = 0; i <= n; i++) sc(A[i]) for (int i = 0; i <4; i++) { build(i, 0, n-1, 1); } int l,r,x; while (m--) { cin >> s; if (s[0] == 'S') { sc(l) sc(r) int ans=0; for(int i=0;i<4;i++){ ans +=query(i,0,n-1,1,l,r)*(1<<i); } cout<<ans<<'\n'; } else if (s[0] == 'X') { sc(x) sc(l) sc(r) for(int i=0;i<4;i++){ if((x>>i)&1){ update(i,0,n-1,1,2,l,r); } } } else if (s[0] == 'O') { sc(x) sc(l) sc(r) for(int i=0;i<4;i++){ if((x>>i)&1){ update(i,0,n-1,1,3,l,r); } } } else { sc(x) sc(l) sc(r) for(int i=0;i<4;i++){ if(!((x>>i)&1)){ update(i,0,n-1,1,4,l,r); } } } } } //system("pause"); }