1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
|
const int N=2e5+10; namespace MAIN{ int n,q; int cnt[N<<2][30]; int Xor[N<<2]; int mn[N<<2],smn[N<<2],cmn[N<<2]; inline void pushup(const res &rt){ if(mn[rt<<1]<mn[rt<<1|1]){ mn[rt]=mn[rt<<1],cmn[rt]=cmn[rt<<1]; if(smn[rt<<1]<mn[rt<<1|1])smn[rt]=smn[rt<<1]; else smn[rt]=mn[rt<<1|1]; } else if(mn[rt<<1]>mn[rt<<1|1]){ mn[rt]=mn[rt<<1|1],cmn[rt]=cmn[rt<<1|1]; if(smn[rt<<1|1]<mn[rt<<1])smn[rt]=smn[rt<<1|1]; else smn[rt]=mn[rt<<1]; } else mn[rt]=mn[rt<<1],cmn[rt]=cmn[rt<<1]+cmn[rt<<1|1],smn[rt]=min(smn[rt<<1],smn[rt<<1|1]); for(res i=0;i<30;i++)cnt[rt][i]=cnt[rt<<1][i]+cnt[rt<<1|1][i]; Xor[rt]=Xor[rt<<1]^Xor[rt<<1|1]; } int tag[N<<2]; void build(res rt,res l,res r){ tag[rt]=-1; if(l==r){ res x=read(); mn[rt]=Xor[rt]=x,cmn[rt]=1,smn[rt]=1<<30; for(res i=29;~i;i--)if((x>>i)&1)cnt[rt][i]=1; return; } res mid=(l+r)>>1; build(rt<<1,l,mid),build(rt<<1|1,mid+1,r),pushup(rt); } inline void change(const res &rt,const res &x){ if(mn[rt]>=x)return; for(res i=29;~i;i--)if((mn[rt]>>i)&1)cnt[rt][i]-=cmn[rt]; if(cmn[rt]&1)Xor[rt]^=mn[rt]; for(res i=29;~i;i--)if((x>>i)&1)cnt[rt][i]+=cmn[rt]; mn[rt]=x; if(cmn[rt]&1)Xor[rt]^=x; tag[rt]=x; } inline void pushdown(const res &rt){ if(tag[rt]==-1)return; change(rt<<1,tag[rt]),change(rt<<1|1,tag[rt]),tag[rt]=-1; } void modify(res rt,res l,res r,const res &L,const res &R,const res &x){ if(mn[rt]>=x)return; if(l==r){ for(res i=29;~i;i--)if((mn[rt]>>i)&1)cnt[rt][i]=0; for(res i=29;~i;i--)if((x>>i)&1)cnt[rt][i]=1; mn[rt]=x,Xor[rt]=x; return; } if(L<=l&&r<=R){ if(smn[rt]>x){change(rt,x);return;} } pushdown(rt); res mid=(l+r)>>1; if(L<=mid)modify(rt<<1,l,mid,L,R,x); if(R>mid)modify(rt<<1|1,mid+1,r,L,R,x); pushup(rt); } int query_xor(res rt,res l,res r,const res &L,const res &R){ if(L<=l&&r<=R)return Xor[rt]; pushdown(rt); res mid=(l+r)>>1,ret=0; if(L<=mid)ret=query_xor(rt<<1,l,mid,L,R); if(R>mid)ret^=query_xor(rt<<1|1,mid+1,r,L,R); pushup(rt); return ret; } int query(res rt,res l,res r,const res &L,const res &R,const res &p){ if(L<=l&&r<=R)return cnt[rt][p]; pushdown(rt); res mid=(l+r)>>1,ret=0; if(L<=mid)ret=query(rt<<1,l,mid,L,R,p); if(R>mid)ret+=query(rt<<1|1,mid+1,r,L,R,p); pushup(rt); return ret; } inline void MAIN(){ n=read(),q=read(),build(1,1,n); while(q--){ res opt=read(),l=read(),r=read(),x=read(); if(opt==1){ modify(1,1,n,l,r,x); } else { res s=query_xor(1,1,n,l,r)^x; if(s==0)puts("0"); else { res ret=0; for(res i=29;~i;i--)if((s>>i)){ret=query(1,1,n,l,r,i);break;} printf("%d\n",ret+((x^s)<=x)); } } } } }
|