#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cmath>
#include<cstring>
#define ll long long
using namespace std;
const int N=1e5+10;
typedef pair<int,int> PII;
int n,a[N],m;
#define ls(x) x<<1
#define rs(x) x<<1|1
struct tree
{
int l,r;
int add,val,w[21];
}t[N<<2];
void pushup(int x)
{
t[x].val=t[ls(x)].val+t[rs(x)].val;
for(int i=0;i<=20;i++)
t[x].w[i]=t[ls(x)].w[i]+t[rs(x)].w[i];
}
void solve(int x,int v)
{
int cnt=0;
while(v)
{
if(v&1)
{
t[x].w[cnt]=(t[x].r-t[x].l+1-t[x].w[cnt]);
}
v>>=1;
cnt++;
}
t[x].val=0;
for(int i=0;i<=20;i++)
{
t[x].val+=(1<<i)*t[x].w[i];
}
}
void build(int x,int l,int r)
{
t[x].l=l,t[x].r=r;
if(l==r)
{
solve(x,a[l]);
return;
}
int mid=(l+r)>>1;
build(ls(x),l,mid),build(rs(x),mid+1,r);
pushup(x);
}
void pushdown(int x)
{
if(!t[x].add) return;
solve(ls(x),t[x].add);
solve(rs(x),t[x].add);
t[ls(x)].add^=t[x].add;
t[rs(x)].add^=t[x].add;
t[x].add=0;
}
void update(int x,int l,int r,int v)
{
if(t[x].l>=l&&t[x].r<=r)
{
solve(x,v);
t[x].add^=v;
return;
}
pushdown(x);
int mid=(t[x].l+t[x].r)>>1;
if(l<=mid) update(ls(x),l,r,v);
if(r>mid) update(rs(x),l,r,v);
pushup(x);
}
int query(int x,int l,int r)
{
if(t[x].l>=l&&t[x].r<=r)
return t[x].val;
pushdown(x);
int mid=(t[x].l+t[x].r)>>1,ans=0;
if(l<=mid) ans+=query(ls(x),l,r);
if(r>mid) ans+=query(rs(x),l,r);
return ans;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
build(1,1,n);
cin>>m;
while(m--)
{
int op,l,r,x;
cin>>op>>l>>r;
if(op==1) cout<<query(1,l,r)<<'\n';
else
{
cin>>x;
update(1,l,r,x);
}
}
return 0;
}