链接:
http://codeforces.com/contest/242/problem/E
题意:
维护一个长度为n的数列,有2中操作
1.询问[l,r]的区间和
2.将[l,r]之间的所有数都异或x
题解:
用线段树来维护每一位1的个数就可以了
代码:
31 int n, m; 32 int a[MAXN]; 33 int Tree[25][MAXN << 2], Lazy[25][MAXN << 2]; 34 35 void pushup(int pos, int rt) { 36 Tree[pos][rt] = Tree[pos][rt << 1] + Tree[pos][rt << 1 | 1]; 37 } 38 39 void pushdown(int pos, int l, int r, int rt) { 40 if (Lazy[pos][rt]) { 41 int m = (l + r) >> 1; 42 Tree[pos][rt << 1] = m - l + 1 - Tree[pos][rt << 1]; 43 Tree[pos][rt << 1 | 1] = r - m - Tree[pos][rt << 1 | 1]; 44 Lazy[pos][rt << 1] ^= 1; 45 Lazy[pos][rt << 1 | 1] ^= 1; 46 Lazy[pos][rt] = 0; 47 } 48 } 49 50 void build(int pos, int l, int r, int rt) { 51 if (l == r) { 52 Tree[pos][rt] = a[l] & 1; 53 a[l] >>= 1; 54 return; 55 } 56 int m = (l + r) >> 1; 57 build(pos, lson); 58 build(pos, rson); 59 pushup(pos, rt); 60 } 61 62 void update(int pos,int L,int R, int l, int r, int rt) { 63 if (L <= l && r <= R) { 64 Tree[pos][rt] = r - l + 1 - Tree[pos][rt]; 65 Lazy[pos][rt] ^= 1; 66 return; 67 } 68 pushdown(pos, l, r, rt); 69 int m = (l + r) >> 1; 70 if (L <= m) update(pos, L, R, lson); 71 if (R > m) update(pos, L, R, rson); 72 pushup(pos, rt); 73 } 74 75 int query(int pos, int L, int R, int l, int r, int rt) { 76 if (L <= l && r <= R) return Tree[pos][rt]; 77 pushdown(pos, l, r, rt); 78 int m = (l + r) >> 1; 79 int ret = 0; 80 if (L <= m) ret += query(pos, L, R, lson); 81 if (R > m) ret += query(pos, L, R, rson); 82 return ret; 83 } 84 85 int main() { 86 ios::sync_with_stdio(false), cin.tie(0); 87 cin >> n; 88 rep(i, 1, n + 1) cin >> a[i]; 89 rep(i, 0, 25) build(i, 1, n, 1); 90 cin >> m; 91 while (m--) { 92 int t, l, r, x; 93 cin >> t >> l >> r; 94 if (t == 1) { 95 ll ans = 0; 96 ll cnt = 1; 97 rep(i, 0, 25) { 98 ans += cnt*query(i, l, r, 1, n, 1); 99 cnt *= 2; 100 } 101 cout << ans << endl; 102 } 103 else { 104 cin >> x; 105 rep(i, 0, 25) { 106 if (x & 1) update(i, l, r, 1, n, 1); 107 x >>= 1; 108 } 109 } 110 } 111 return 0; 112 }