题解
#include<bits/stdc++.h>
#define ll long long
#define reg register
#define db double
#define il inline
using namespace std;
void read(int &x){x=0;int f=1;char c=getchar();while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}x*=f;}
void read(ll &x){x=0;int f=1;char c=getchar();while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}x*=f;}
const int N=2e5+5;
int n,q,a[N];
struct node{
int minn,mncnt,se,cnt[35],tag,summ;
}tree[N<<2];
void push_up(int x){
int ls=x<<1,rs=x<<1|1;
tree[x].summ=tree[ls].summ^tree[rs].summ;
for(int i=0;i<30;i++){tree[x].cnt[i]=tree[ls].cnt[i]+tree[rs].cnt[i];}
if(tree[ls].minn<tree[rs].minn){
tree[x].minn=tree[ls].minn;
tree[x].se=min(tree[ls].se,tree[rs].minn);
tree[x].mncnt=tree[ls].mncnt;
}else if(tree[ls].minn>tree[rs].minn){
swap(ls,rs);tree[x].minn=tree[ls].minn;
tree[x].se=min(tree[ls].se,tree[rs].minn);
tree[x].mncnt=tree[ls].mncnt;swap(ls,rs);
}else{
tree[x].minn=tree[ls].minn;tree[x].mncnt=tree[ls].mncnt+tree[rs].mncnt;
tree[x].se=min(tree[ls].se,tree[rs].se);
}
}
void build(int x,int l,int r){
tree[x].tag=-1;
if(l==r){
tree[x].minn=tree[x].summ=a[l];tree[x].se=((1ll<<35)+1);tree[x].mncnt=1;
for(int i=0;i<30;i++){
if((1<<i)&a[l])tree[x].cnt[i]=1;
}
return;
}
int mid=(l+r)/2;
build(x<<1,l,mid);build(x<<1|1,mid+1,r);
push_up(x);
}
void set_tag(int x,int v){
if(tree[x].minn>=v)return;
tree[x].summ=tree[x].summ^((tree[x].mncnt&1)*(tree[x].minn^v));
for(int i=0;i<30;i++){
if(tree[x].minn&(1<<i))tree[x].cnt[i]-=tree[x].mncnt;
if(v&(1<<i))tree[x].cnt[i]+=tree[x].mncnt;
}
tree[x].minn=v;tree[x].tag=v;
}
void push_down(int x){
if(tree[x].tag==-1)return;
set_tag(x<<1,tree[x].tag);set_tag(x<<1|1,tree[x].tag);tree[x].tag=-1;
}
int query1(int x,int l,int r,int ql,int qr){
if(ql<=l&&qr>=r)return tree[x].summ;
push_down(x);
int re=0,mid=(l+r)/2;
if(ql<=mid)re=query1(x<<1,l,mid,ql,qr);
if(qr>mid)re^=query1(x<<1|1,mid+1,r,ql,qr);
return re;
}
int query2(int x,int l,int r,int ql,int qr,int v){
if(ql<=l&&qr>=r){
return tree[x].cnt[v];
}
push_down(x);
int re=0,mid=(l+r)/2;
if(ql<=mid)re=query2(x<<1,l,mid,ql,qr,v);
if(qr>mid)re+=query2(x<<1|1,mid+1,r,ql,qr,v);
return re;
}
void update(int x,int l,int r,int ql,int qr,int v){
if(tree[x].minn>=v)return;
if(ql<=l&&qr>=r&&tree[x].se>v){
set_tag(x,v);return;
}
push_down(x);
int mid=(l+r)/2;
if(ql<=mid)update(x<<1,l,mid,ql,qr,v);
if(qr>mid)update(x<<1|1,mid+1,r,ql,qr,v);
push_up(x);
}
signed main(){
read(n);read(q);
for(int i=1;i<=n;i++)read(a[i]);
build(1,1,n);
int op,l,r,x;
while(q--){
read(op);read(l);read(r);read(x);
if(op==1){
update(1,1,n,l,r,x);
}else{
int tmp=query1(1,1,n,l,r);tmp^=x;
if(!tmp)puts("0");
else for(int i=29;i>=0;i--){
if(tmp&(1<<i)){
printf("%d\n",query2(1,1,n,l,r,i)+(x&(1<<i)));break;
}
}
}
}
return 0;
}