#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <set> #include <vector> #include <map> #include <queue> #include <set> #include <algorithm> #include <limits> using namespace std; typedef long long LL; const int MAXN=1000000+1000; const int INF = numeric_limits<int>::max(); const LL LL_INF= numeric_limits<LL>::max(); #define lson L,mid,rt<<1 #define rson mid+1,R,rt<<1|1 struct Tree { int cnt[4]; int flag[4]; bool v[4]; }tr[MAXN<<2]; void pushup(int rt){ for(int i=0;i<4;i++){ tr[rt].cnt[i]=tr[rt<<1].cnt[i]+tr[rt<<1|1].cnt[i]; } } void pushdownA(int L,int R,int rt); void pushdownB(int L,int R,int rt); void pushdownC(int L,int R,int rt); void pushdownA(int L,int R,int rt){ if(L==R)return ; int mid=(L+R)>>1; for(int i=0;i<4;i++){ if(tr[rt].flag[i]&1){ tr[rt<<1].cnt[i]=(mid-L+1); tr[rt<<1|1].cnt[i]=(R-(mid+1)+1); tr[rt<<1].flag[i]=tr[rt<<1|1].flag[i]=tr[rt].flag[i]; tr[rt].flag[i]=0; tr[rt].v[i]=0; } } } void pushdownB(int L,int R,int rt){ if(L==R)return ; for(int i=0;i<4;i++){ if(tr[rt].flag[i]&2){ tr[rt<<1].cnt[i]=0; tr[rt<<1|1].cnt[i]=0; tr[rt<<1].flag[i]=tr[rt<<1|1].flag[i]=tr[rt].flag[i]; tr[rt].flag[i]=0; tr[rt].v[i]=0; } } } void pushdownC(int L,int R,int rt){ int mid=(L+R)>>1; for(int i=0;i<4;i++){ if(tr[rt].flag[i]&4){ if(tr[rt<<1].flag[i]&1)pushdownA(lson); if(tr[rt<<1].flag[i]&2)pushdownB(lson); if(tr[rt<<1|1].flag[i]&1)pushdownA(rson); if(tr[rt<<1|1].flag[i]&2)pushdownB(rson); if(tr[rt].v[i]){ tr[rt<<1].cnt[i]=mid-L+1-tr[rt<<1].cnt[i]; tr[rt<<1|1].cnt[i]=R-(mid+1)+1-tr[rt<<1|1].cnt[i]; tr[rt<<1].v[i]^=1; tr[rt<<1|1].v[i]^=1; } tr[rt<<1].flag[i]=tr[rt<<1|1].flag[i]=tr[rt].flag[i]; tr[rt].flag[i]=0; tr[rt].v[i]=0; } } } void pushdown(int L,int R,int rt){ if(L==R)return ; pushdownA(L,R,rt); pushdownB(L,R,rt); pushdownC(L,R,rt); } int A[MAXN]; void build(int L,int R,int rt){ memset(&tr[rt],0,sizeof(Tree)); if(L==R){ for(int i=0;i<4;i++) tr[rt].cnt[i]=(A[L]>>i)&1; return ; } int mid=(L+R)>>1; build(lson);build(rson); pushup(rt); } void update(int L,int R,int rt,int l,int r,int flag,int pos){ pushdown(L,R,rt); if(l<=L&&R<=r){ if(flag&1){ tr[rt].cnt[pos]=(R-L+1); tr[rt].flag[pos]=flag; } if(flag&2){ tr[rt].cnt[pos]=0; tr[rt].flag[pos]=flag; } if(flag&4){ tr[rt].cnt[pos]=(R-L+1)-tr[rt].cnt[pos]; tr[rt].flag[pos]=flag; tr[rt].v[pos]=1; } return ; } int mid=(L+R)>>1; if(l<=mid)update(lson,l,r,flag,pos); if(r>mid)update(rson,l,r,flag,pos); pushup(rt); return ; } int query(int L,int R,int rt,int l,int r,int pos){ pushdown(L,R,rt); if(l<=L&&R<=r)return tr[rt].cnt[pos]; int mid=(L+R)>>1,ans=0; if(l<=mid)ans+=query(lson,l,r,pos); if(r>mid)ans+=query(rson,l,r,pos); pushup(rt); return ans; } int main() { int t,n,m; scanf("%d",&t); while(t--){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++)scanf("%d",&A[i]); build(1,n,1); char strs[10]; for(int i=0,l,r,v;i<m;i++){ scanf(" %s",strs); if(strs[0]=='S'){ scanf("%d%d",&l,&r); ++l;++r; int ans=query(1,n,1,l,r,0)+query(1,n,1,l,r,1)*2+query(1,n,1,l,r,2)*4+query(1,n,1,l,r,3)*8; printf("%d\n",ans); } if(strs[0]=='X'){ scanf("%d%d%d",&v,&l,&r); ++l;++r; for(int i=0;i<4;i++){ if((v>>i)&1)update(1,n,1,l,r,4,i); } } if(strs[0]=='O'){ scanf("%d%d%d",&v,&l,&r); ++l;++r; for(int i=0;i<4;i++){ if((v>>i)&1)update(1,n,1,l,r,1,i); } } if(strs[0]=='A'){ scanf("%d%d%d",&v,&l,&r); ++l;++r; for(int i=0;i<4;i++){ if(((v>>i)&1)==0)update(1,n,1,l,r,2,i); } } } } return 0; }
|