#include <bits/stdc++.h>
using namespace std;
long long pot[20];
struct st {
  int l, r, sz, vet[20];
  st() {
    for (int i = 0; i < 20; i++) vet[i] = 0;
  }
  st(int x, int y, int z) {
    l = y;
    r = z;
    sz = r - l + 1;
    for (int i = 0; i < 20; i++) {
      if (pot[i] & x)
        vet[i] = 1;
      else
        vet[i] = 0;
    }
  }
  void operator^=(int x) {
    for (int i = 0; i < 20; i++)
      if (pot[i] & x) vet[i] = sz - vet[i];
  }
  st operator+(st st2) {
    st st3;
    st3.l = l;
    st3.r = st2.r;
    st3.sz = st3.r - st3.l + 1;
    for (int i = 0; i < 20; i++) st3.vet[i] += vet[i] + st2.vet[i];
    return st3;
  }
  long long sum() {
    long long ans = 0;
    for (int i = 0; i < 20; i++) ans += vet[i] * pot[i];
    return ans;
  }
};
int N, Q;
st tree[4 * 100005];
int lazy[4 * 100005];
int A[100005];
void build(int node, int start, int end) {
  if (start == end)
    tree[node] = st(A[start], start, end);
  else {
    int mid = (start + end) / 2;
    build(2 * node, start, mid);
    build(2 * node + 1, mid + 1, end);
    tree[node] = tree[2 * node] + tree[2 * node + 1];
  }
}
void updateRange(int node, int start, int end, int l, int r, int val) {
  if (lazy[node]) {
    tree[node] ^= lazy[node];
    if (start != end) {
      lazy[node * 2] ^= lazy[node];
      lazy[node * 2 + 1] ^= lazy[node];
    }
    lazy[node] = 0;
  }
  if (start > end || start > r || end < l) return;
  if (start >= l && end <= r) {
    tree[node] ^= val;
    if (start != end) {
      lazy[node * 2] ^= val;
      lazy[node * 2 + 1] ^= val;
    }
    return;
  }
  int mid = (start + end) / 2;
  updateRange(node * 2, start, mid, l, r, val);
  updateRange(node * 2 + 1, mid + 1, end, l, r, val);
  tree[node] = tree[node * 2] + tree[node * 2 + 1];
}
st queryRange(int node, int start, int end, int l, int r) {
  if (start > end || start > r || end < l) return st();
  if (lazy[node]) {
    tree[node] ^= lazy[node];
    if (start != end) {
      lazy[node * 2] ^= lazy[node];
      lazy[node * 2 + 1] ^= lazy[node];
    }
    lazy[node] = 0;
  }
  if (start >= l && end <= r) return tree[node];
  int mid = (start + end) / 2;
  st p1 = queryRange(node * 2, start, mid, l, r);
  st p2 = queryRange(node * 2 + 1, mid + 1, end, l, r);
  return (p1 + p2);
}
long long sum(int l, int r) { return queryRange(1, 1, N, l, r).sum(); }
int main() {
  int op, x, y, z;
  pot[0] = 1;
  for (int i = 1; i < 20; i++) pot[i] = pot[i - 1] << 1;
  scanf("%d", &N);
  for (int i = 1; i <= N; i++) scanf("%d", &A[i]);
  build(1, 1, N);
  scanf("%d", &Q);
  while (Q--) {
    scanf("%d", &op);
    if (op == 1) {
      scanf("%d %d", &x, &y);
      printf("%lld\n", sum(x, y));
    } else {
      scanf("%d %d %d", &x, &y, &z);
      updateRange(1, 1, N, x, y, z);
    }
  }
  return 0;
}
