给定 n 个数的序列 a。m 次操作,操作有两种:
1.求
∑
i
=
l
r
a
i
\displaystyle\sum_{i=l}^r a_i
i=l∑rai
2.把
a
l
∼
a
r
a_l\sim a_r
al∼ar异或上x
const int MAXN = 100005, MAXW = 25;
int n, v[MAXW][MAXN];
struct Segment_tree {
int n, val[MAXN << 2], tag[MAXN << 2];
void Clear() {mst(val, 0); mst(tag, 0); n = 0;}
#define ls (k << 1)
#define rs (k << 1 | 1)
#define mid ((l + r) >> 1)
void Build(int num, int k, int l, int r) {
if(l == r) {val[k] = v[num][l], tag[k] = 0; return;}
Build(num, ls, l, mid); Build(num, rs, mid+1, r);
val[k] = val[ls] + val[rs];
}
void pushdown(int k, int l, int r) {
if(tag[k]) {
tag[k] = 0, tag[ls] ^= 1, tag[rs] ^= 1;
val[ls] = (mid-l+1) - val[ls];
val[rs] = (r - mid) - val[rs];
}
}
int query(int k, int l, int r, int ql, int qr) {
if(l == ql && r == qr) return val[k];
pushdown(k, l, r); assert(l <= r);
if(qr <= mid) return query(ls, l, mid, ql, qr);
else if(mid < ql) return query(rs, mid+1, r, ql, qr);
else return query(ls, l, mid, ql, mid) + query(rs, mid+1, r, mid+1, qr);
}
int Query(int l, int r) {return query(1, 1, n, l, r);}
void rev(int k, int l, int r, int rl, int rr) {
if(l == rl && r == rr) {
tag[k] ^= 1; val[k] = (r - l + 1) - val[k];
return;
}
pushdown(k, l, r);
if(rr <= mid) rev(ls, l, mid, rl, rr);
else if(mid < rl) rev(rs, mid+1, r, rl, rr);
else {rev(ls, l, mid, rl, mid); rev(rs, mid+1, r, mid+1, rr);}
val[k] = val[ls] + val[rs];
}
void Reverse(int l, int r) {rev(1, 1, n, l, r);}
}tr[MAXW];
signed main()
{
cin >> n;
For(i, 1, n) {
int x = read();
for(int j = 0; (1 << j) <= x; j++)
v[j][i] = (x >> j) & 1;
}
For(i, 0, 20) {
tr[i].Clear(); tr[i].n = n;
tr[i].Build(i, 1, 1, n);
}
int Qnum = read();
while(Qnum--) {
int op = read(), l = read(), r = read();
if(op == 1) {
int ans = 0;
For(i, 0, 20)
ans += tr[i].Query(l, r) * (1ll << i);
printf("%lld\n", ans);
} else {
int x = read();
For(i, 0, 20)
if((x >> i) & 1)
tr[i].Reverse(l, r);
}
}
return 0;
}